NodeBB DocumentationRelease 041
The NodeBB Team (httpsgithubcomNodeBBNodeBBgraphscontributors)
thg 9 27 2017
Contents
1 Cagravei dt NodeBB 311 Cagravei dt NodeBB theo HETHH 312 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 10
2 Cu higravenh NodeBB 1721 Configuring Databases 1722 Configuring Web Server Proxies 20
3 Chy NodeBB 2531 Running NodeBB 25
4 Cp nht NodeBB 2741 Upgrading NodeBB 27
5 Qun tr NodeBB 3151 Administrative Functions 3152 Social Network SSOs 3353 Image Hosting APIs 34
6 ETHoacuteng goacutep cho NodeBB 3561 NodeBB Style Guide 3562 Core Modules 36
7 H thng plugin 3971 Writing Plugins for NodeBB 3972 Available Hooks 4273 Settings Framework 47
8 H thng widgets 5581 Writing Widgets for NodeBB 55
9 Nn tng giao din 5791 Creating a new NodeBB Theme 5792 Rendering Engine 58
10 Tagravei nguyecircn cho nhagrave phaacutet trin 63101 Developerrsquos Resources 63
i
11 Tr giuacutep cho d aacuten NodeBB 65111 Helping out the NodeBB Project 65
12 Khc phc Tr giuacutep 67121 Need Help 67
13 Ch muc vagrave bng 71
ii
NodeBB Documentation Release 041
NodeBB lagrave mt nn tng din dagraven th h mi s dng cocircng ngh web sockets d coacute th tng taacutec ngay lp tc vagrave thocircng baacuteo thi gian thcNodeBB coacute nhiu tiacutenh nang hin di vi t duy saacuteng to nh tng taacutec mng xatilde hi vagrave dograveng chy tho lun
NodeBB lagrave mt d aacuten matilde ngun m magrave coacute th to nhaacutenh trecircn GitHub ETHng b qua caacutec caacutech magrave bn coacute th giuacutep d doacuteng goacutep chod aacuten nagravey t dch thut yecircu cu ldquopullrdquo vagrave chia s vi bn begrave ca bn
Contents 1
NodeBB Documentation Release 041
2 Contents
CHAPTER 1
Cagravei dt NodeBB
Cagravei dt NodeBB theo HETHH
Di dacircy lagrave hng dn tng bc d giuacutep bn cagravei dt vagrave chy
Ghi chuacute Nu h diu hagravenh ca bn khocircng coacute trong danh saacutech hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc cograven tt hnhatildey d trigravenh lecircn
Arch Linux
ETHu tiecircn chuacuteng ta cagravei dt goacutei phn mm c bn trc Hatildey thc hin pacman -Syu trc tiecircn d chc chaacuten rng bn datilde dng b vi kho vagrave ttc caacutec goacutei dc cp nht
$ sudo pacman -S git nodejs redis imagemagick
Nu bn mun s dng MongoDB LevelDB hoc mt nn tng c s d liu khaacutec ngoagravei Redis hatildey dc tagravei liu Cu higravenh c s d liu
Tip theo to bn sao ca kho sau
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc dc yecircu cu bi NodeBB
$ cd nodebb$ npm install
Bt du don matilde cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
3
NodeBB Documentation Release 041
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Ubuntu
ETHu tiecircn chuacuteng ta cagravei dt caacutec trigravenh nn
$ sudo apt-get install git nodejs redis-server imagemagick npm
Nu bn mun s dng MongoDB LevelDB hoc mt c s d liu khaacutec thay cho Redis xin dc Cu higravenh c s d liu
Nu trigravenh qun lyacute goacutei ca bn ch cagravei dt phiecircn bn Nodejs nh hn 08 (vd Ubuntu 1210 1304) dugraveng lnh lsquolsquonodendashversionlsquolsquo d xaacutec dnh phiecircn bn Nodejs ca bn
$ sudo add-apt-repository ppachris-leanodejs$ sudo apt-get update ampamp sudo apt-get dist-upgrade
Nu bn mun cagravei dt Nodejs v011 s dng url repo sau ppachris-leanodejs-devel
Sau doacute to bn sao repo
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc bi NodeBB
$ cd nodebb$ npm install
Thc hin cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Debian
Hng dn trecircn Ubuntu hin ti khocircng hoagraven toagraven tng thiacutech vi Debian vagrave coacute mt vagravei neacutet dc trng vagrave dc bit lagrave caacutech cagravei dt Nodejsvagrave caacutech ly dc bn mi nht ca Redis
Yecircu cu
NodeBB cn coacute caacutec phn mm sau dc cagravei dt
bull Nodejs iacutet nht lagrave bn 010 hoc cao hn
bull Redis bn 26 hoc cao hn
bull cURL ch cn thc hin lnh sudo apt-get install curl d cagravei dt
4 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Cagravei dt Nodejs
Debian 7 vagrave 6 hoc cu hn mc dnh khocircng coacute goacutei cagravei dt nodejs nhng coacute mt vagravei gii phaacutep d cagravei dt Nodejs trecircn Debian cabn
Wheezy Backport
Gii phaacutep nagravey CH cho Debian 7 dn gin lagrave chy don matilde di dacircy vi quyn root
$ echo deb httpftpusdebianorgdebian wheezy-backports main gtgt etcaptrarr˓sourceslist$ apt-get update
ETH cagravei dt Nodejs + NPM chy
$ apt-get install nodejs-legacy$ curl --insecure httpswwwnpmjsorginstallsh | bash
Noacute s cagravei dt mt phiecircn bn Nodejs ln hn 08 (vagraveo 29 thaacuteng 3 nam 2014 01021)
Tp hp t ngun
Gii phaacutep nagravey cho Debian 6 (Squeeze) vagrave hn d cagravei dt NodeJS chy don matilde sau vi quyn root
$ sudo apt-get install python g++ make checkinstall$ src=$(mktemp -d) ampamp cd $src$ wget -N httpnodejsorgdistnode-latesttargz$ tar xzvf node-latesttargz ampamp cd node-v$ configure$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -resrarr˓+node-v(+)$1p) make -j$(($(nproc)+1)) install$ sudo dpkg -i node_
Ly phiecircn bn mi nht qua DotDeb
Dotdeb lagrave mt kho cha caacutec goacutei d bin caacutec box Debian ca bn thagravenh mnh m n dnh vagrave LAMP dc cp nht
bull Nginx
bull PHP 54 vagrave 53 (Nhng trigravenh m rng PHP hu iacutech APC imagick Pinba xcache Xdebug XHpro)
bull MySQL 55
bull Percona toolkit
bull Redis
bull Zabbix
bull Passenger
Dotdeb h tr
bull Debian 60 ldquoSqueezeldquo vagrave 7 ldquoWheezyldquo
bull c 2 kin truacutec amd64 vagrave i386
11 Cagravei dt NodeBB theo HETHH 5
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
Contents
1 Cagravei dt NodeBB 311 Cagravei dt NodeBB theo HETHH 312 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 10
2 Cu higravenh NodeBB 1721 Configuring Databases 1722 Configuring Web Server Proxies 20
3 Chy NodeBB 2531 Running NodeBB 25
4 Cp nht NodeBB 2741 Upgrading NodeBB 27
5 Qun tr NodeBB 3151 Administrative Functions 3152 Social Network SSOs 3353 Image Hosting APIs 34
6 ETHoacuteng goacutep cho NodeBB 3561 NodeBB Style Guide 3562 Core Modules 36
7 H thng plugin 3971 Writing Plugins for NodeBB 3972 Available Hooks 4273 Settings Framework 47
8 H thng widgets 5581 Writing Widgets for NodeBB 55
9 Nn tng giao din 5791 Creating a new NodeBB Theme 5792 Rendering Engine 58
10 Tagravei nguyecircn cho nhagrave phaacutet trin 63101 Developerrsquos Resources 63
i
11 Tr giuacutep cho d aacuten NodeBB 65111 Helping out the NodeBB Project 65
12 Khc phc Tr giuacutep 67121 Need Help 67
13 Ch muc vagrave bng 71
ii
NodeBB Documentation Release 041
NodeBB lagrave mt nn tng din dagraven th h mi s dng cocircng ngh web sockets d coacute th tng taacutec ngay lp tc vagrave thocircng baacuteo thi gian thcNodeBB coacute nhiu tiacutenh nang hin di vi t duy saacuteng to nh tng taacutec mng xatilde hi vagrave dograveng chy tho lun
NodeBB lagrave mt d aacuten matilde ngun m magrave coacute th to nhaacutenh trecircn GitHub ETHng b qua caacutec caacutech magrave bn coacute th giuacutep d doacuteng goacutep chod aacuten nagravey t dch thut yecircu cu ldquopullrdquo vagrave chia s vi bn begrave ca bn
Contents 1
NodeBB Documentation Release 041
2 Contents
CHAPTER 1
Cagravei dt NodeBB
Cagravei dt NodeBB theo HETHH
Di dacircy lagrave hng dn tng bc d giuacutep bn cagravei dt vagrave chy
Ghi chuacute Nu h diu hagravenh ca bn khocircng coacute trong danh saacutech hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc cograven tt hnhatildey d trigravenh lecircn
Arch Linux
ETHu tiecircn chuacuteng ta cagravei dt goacutei phn mm c bn trc Hatildey thc hin pacman -Syu trc tiecircn d chc chaacuten rng bn datilde dng b vi kho vagrave ttc caacutec goacutei dc cp nht
$ sudo pacman -S git nodejs redis imagemagick
Nu bn mun s dng MongoDB LevelDB hoc mt nn tng c s d liu khaacutec ngoagravei Redis hatildey dc tagravei liu Cu higravenh c s d liu
Tip theo to bn sao ca kho sau
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc dc yecircu cu bi NodeBB
$ cd nodebb$ npm install
Bt du don matilde cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
3
NodeBB Documentation Release 041
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Ubuntu
ETHu tiecircn chuacuteng ta cagravei dt caacutec trigravenh nn
$ sudo apt-get install git nodejs redis-server imagemagick npm
Nu bn mun s dng MongoDB LevelDB hoc mt c s d liu khaacutec thay cho Redis xin dc Cu higravenh c s d liu
Nu trigravenh qun lyacute goacutei ca bn ch cagravei dt phiecircn bn Nodejs nh hn 08 (vd Ubuntu 1210 1304) dugraveng lnh lsquolsquonodendashversionlsquolsquo d xaacutec dnh phiecircn bn Nodejs ca bn
$ sudo add-apt-repository ppachris-leanodejs$ sudo apt-get update ampamp sudo apt-get dist-upgrade
Nu bn mun cagravei dt Nodejs v011 s dng url repo sau ppachris-leanodejs-devel
Sau doacute to bn sao repo
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc bi NodeBB
$ cd nodebb$ npm install
Thc hin cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Debian
Hng dn trecircn Ubuntu hin ti khocircng hoagraven toagraven tng thiacutech vi Debian vagrave coacute mt vagravei neacutet dc trng vagrave dc bit lagrave caacutech cagravei dt Nodejsvagrave caacutech ly dc bn mi nht ca Redis
Yecircu cu
NodeBB cn coacute caacutec phn mm sau dc cagravei dt
bull Nodejs iacutet nht lagrave bn 010 hoc cao hn
bull Redis bn 26 hoc cao hn
bull cURL ch cn thc hin lnh sudo apt-get install curl d cagravei dt
4 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Cagravei dt Nodejs
Debian 7 vagrave 6 hoc cu hn mc dnh khocircng coacute goacutei cagravei dt nodejs nhng coacute mt vagravei gii phaacutep d cagravei dt Nodejs trecircn Debian cabn
Wheezy Backport
Gii phaacutep nagravey CH cho Debian 7 dn gin lagrave chy don matilde di dacircy vi quyn root
$ echo deb httpftpusdebianorgdebian wheezy-backports main gtgt etcaptrarr˓sourceslist$ apt-get update
ETH cagravei dt Nodejs + NPM chy
$ apt-get install nodejs-legacy$ curl --insecure httpswwwnpmjsorginstallsh | bash
Noacute s cagravei dt mt phiecircn bn Nodejs ln hn 08 (vagraveo 29 thaacuteng 3 nam 2014 01021)
Tp hp t ngun
Gii phaacutep nagravey cho Debian 6 (Squeeze) vagrave hn d cagravei dt NodeJS chy don matilde sau vi quyn root
$ sudo apt-get install python g++ make checkinstall$ src=$(mktemp -d) ampamp cd $src$ wget -N httpnodejsorgdistnode-latesttargz$ tar xzvf node-latesttargz ampamp cd node-v$ configure$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -resrarr˓+node-v(+)$1p) make -j$(($(nproc)+1)) install$ sudo dpkg -i node_
Ly phiecircn bn mi nht qua DotDeb
Dotdeb lagrave mt kho cha caacutec goacutei d bin caacutec box Debian ca bn thagravenh mnh m n dnh vagrave LAMP dc cp nht
bull Nginx
bull PHP 54 vagrave 53 (Nhng trigravenh m rng PHP hu iacutech APC imagick Pinba xcache Xdebug XHpro)
bull MySQL 55
bull Percona toolkit
bull Redis
bull Zabbix
bull Passenger
Dotdeb h tr
bull Debian 60 ldquoSqueezeldquo vagrave 7 ldquoWheezyldquo
bull c 2 kin truacutec amd64 vagrave i386
11 Cagravei dt NodeBB theo HETHH 5
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
11 Tr giuacutep cho d aacuten NodeBB 65111 Helping out the NodeBB Project 65
12 Khc phc Tr giuacutep 67121 Need Help 67
13 Ch muc vagrave bng 71
ii
NodeBB Documentation Release 041
NodeBB lagrave mt nn tng din dagraven th h mi s dng cocircng ngh web sockets d coacute th tng taacutec ngay lp tc vagrave thocircng baacuteo thi gian thcNodeBB coacute nhiu tiacutenh nang hin di vi t duy saacuteng to nh tng taacutec mng xatilde hi vagrave dograveng chy tho lun
NodeBB lagrave mt d aacuten matilde ngun m magrave coacute th to nhaacutenh trecircn GitHub ETHng b qua caacutec caacutech magrave bn coacute th giuacutep d doacuteng goacutep chod aacuten nagravey t dch thut yecircu cu ldquopullrdquo vagrave chia s vi bn begrave ca bn
Contents 1
NodeBB Documentation Release 041
2 Contents
CHAPTER 1
Cagravei dt NodeBB
Cagravei dt NodeBB theo HETHH
Di dacircy lagrave hng dn tng bc d giuacutep bn cagravei dt vagrave chy
Ghi chuacute Nu h diu hagravenh ca bn khocircng coacute trong danh saacutech hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc cograven tt hnhatildey d trigravenh lecircn
Arch Linux
ETHu tiecircn chuacuteng ta cagravei dt goacutei phn mm c bn trc Hatildey thc hin pacman -Syu trc tiecircn d chc chaacuten rng bn datilde dng b vi kho vagrave ttc caacutec goacutei dc cp nht
$ sudo pacman -S git nodejs redis imagemagick
Nu bn mun s dng MongoDB LevelDB hoc mt nn tng c s d liu khaacutec ngoagravei Redis hatildey dc tagravei liu Cu higravenh c s d liu
Tip theo to bn sao ca kho sau
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc dc yecircu cu bi NodeBB
$ cd nodebb$ npm install
Bt du don matilde cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
3
NodeBB Documentation Release 041
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Ubuntu
ETHu tiecircn chuacuteng ta cagravei dt caacutec trigravenh nn
$ sudo apt-get install git nodejs redis-server imagemagick npm
Nu bn mun s dng MongoDB LevelDB hoc mt c s d liu khaacutec thay cho Redis xin dc Cu higravenh c s d liu
Nu trigravenh qun lyacute goacutei ca bn ch cagravei dt phiecircn bn Nodejs nh hn 08 (vd Ubuntu 1210 1304) dugraveng lnh lsquolsquonodendashversionlsquolsquo d xaacutec dnh phiecircn bn Nodejs ca bn
$ sudo add-apt-repository ppachris-leanodejs$ sudo apt-get update ampamp sudo apt-get dist-upgrade
Nu bn mun cagravei dt Nodejs v011 s dng url repo sau ppachris-leanodejs-devel
Sau doacute to bn sao repo
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc bi NodeBB
$ cd nodebb$ npm install
Thc hin cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Debian
Hng dn trecircn Ubuntu hin ti khocircng hoagraven toagraven tng thiacutech vi Debian vagrave coacute mt vagravei neacutet dc trng vagrave dc bit lagrave caacutech cagravei dt Nodejsvagrave caacutech ly dc bn mi nht ca Redis
Yecircu cu
NodeBB cn coacute caacutec phn mm sau dc cagravei dt
bull Nodejs iacutet nht lagrave bn 010 hoc cao hn
bull Redis bn 26 hoc cao hn
bull cURL ch cn thc hin lnh sudo apt-get install curl d cagravei dt
4 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Cagravei dt Nodejs
Debian 7 vagrave 6 hoc cu hn mc dnh khocircng coacute goacutei cagravei dt nodejs nhng coacute mt vagravei gii phaacutep d cagravei dt Nodejs trecircn Debian cabn
Wheezy Backport
Gii phaacutep nagravey CH cho Debian 7 dn gin lagrave chy don matilde di dacircy vi quyn root
$ echo deb httpftpusdebianorgdebian wheezy-backports main gtgt etcaptrarr˓sourceslist$ apt-get update
ETH cagravei dt Nodejs + NPM chy
$ apt-get install nodejs-legacy$ curl --insecure httpswwwnpmjsorginstallsh | bash
Noacute s cagravei dt mt phiecircn bn Nodejs ln hn 08 (vagraveo 29 thaacuteng 3 nam 2014 01021)
Tp hp t ngun
Gii phaacutep nagravey cho Debian 6 (Squeeze) vagrave hn d cagravei dt NodeJS chy don matilde sau vi quyn root
$ sudo apt-get install python g++ make checkinstall$ src=$(mktemp -d) ampamp cd $src$ wget -N httpnodejsorgdistnode-latesttargz$ tar xzvf node-latesttargz ampamp cd node-v$ configure$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -resrarr˓+node-v(+)$1p) make -j$(($(nproc)+1)) install$ sudo dpkg -i node_
Ly phiecircn bn mi nht qua DotDeb
Dotdeb lagrave mt kho cha caacutec goacutei d bin caacutec box Debian ca bn thagravenh mnh m n dnh vagrave LAMP dc cp nht
bull Nginx
bull PHP 54 vagrave 53 (Nhng trigravenh m rng PHP hu iacutech APC imagick Pinba xcache Xdebug XHpro)
bull MySQL 55
bull Percona toolkit
bull Redis
bull Zabbix
bull Passenger
Dotdeb h tr
bull Debian 60 ldquoSqueezeldquo vagrave 7 ldquoWheezyldquo
bull c 2 kin truacutec amd64 vagrave i386
11 Cagravei dt NodeBB theo HETHH 5
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
NodeBB lagrave mt nn tng din dagraven th h mi s dng cocircng ngh web sockets d coacute th tng taacutec ngay lp tc vagrave thocircng baacuteo thi gian thcNodeBB coacute nhiu tiacutenh nang hin di vi t duy saacuteng to nh tng taacutec mng xatilde hi vagrave dograveng chy tho lun
NodeBB lagrave mt d aacuten matilde ngun m magrave coacute th to nhaacutenh trecircn GitHub ETHng b qua caacutec caacutech magrave bn coacute th giuacutep d doacuteng goacutep chod aacuten nagravey t dch thut yecircu cu ldquopullrdquo vagrave chia s vi bn begrave ca bn
Contents 1
NodeBB Documentation Release 041
2 Contents
CHAPTER 1
Cagravei dt NodeBB
Cagravei dt NodeBB theo HETHH
Di dacircy lagrave hng dn tng bc d giuacutep bn cagravei dt vagrave chy
Ghi chuacute Nu h diu hagravenh ca bn khocircng coacute trong danh saacutech hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc cograven tt hnhatildey d trigravenh lecircn
Arch Linux
ETHu tiecircn chuacuteng ta cagravei dt goacutei phn mm c bn trc Hatildey thc hin pacman -Syu trc tiecircn d chc chaacuten rng bn datilde dng b vi kho vagrave ttc caacutec goacutei dc cp nht
$ sudo pacman -S git nodejs redis imagemagick
Nu bn mun s dng MongoDB LevelDB hoc mt nn tng c s d liu khaacutec ngoagravei Redis hatildey dc tagravei liu Cu higravenh c s d liu
Tip theo to bn sao ca kho sau
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc dc yecircu cu bi NodeBB
$ cd nodebb$ npm install
Bt du don matilde cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
3
NodeBB Documentation Release 041
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Ubuntu
ETHu tiecircn chuacuteng ta cagravei dt caacutec trigravenh nn
$ sudo apt-get install git nodejs redis-server imagemagick npm
Nu bn mun s dng MongoDB LevelDB hoc mt c s d liu khaacutec thay cho Redis xin dc Cu higravenh c s d liu
Nu trigravenh qun lyacute goacutei ca bn ch cagravei dt phiecircn bn Nodejs nh hn 08 (vd Ubuntu 1210 1304) dugraveng lnh lsquolsquonodendashversionlsquolsquo d xaacutec dnh phiecircn bn Nodejs ca bn
$ sudo add-apt-repository ppachris-leanodejs$ sudo apt-get update ampamp sudo apt-get dist-upgrade
Nu bn mun cagravei dt Nodejs v011 s dng url repo sau ppachris-leanodejs-devel
Sau doacute to bn sao repo
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc bi NodeBB
$ cd nodebb$ npm install
Thc hin cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Debian
Hng dn trecircn Ubuntu hin ti khocircng hoagraven toagraven tng thiacutech vi Debian vagrave coacute mt vagravei neacutet dc trng vagrave dc bit lagrave caacutech cagravei dt Nodejsvagrave caacutech ly dc bn mi nht ca Redis
Yecircu cu
NodeBB cn coacute caacutec phn mm sau dc cagravei dt
bull Nodejs iacutet nht lagrave bn 010 hoc cao hn
bull Redis bn 26 hoc cao hn
bull cURL ch cn thc hin lnh sudo apt-get install curl d cagravei dt
4 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Cagravei dt Nodejs
Debian 7 vagrave 6 hoc cu hn mc dnh khocircng coacute goacutei cagravei dt nodejs nhng coacute mt vagravei gii phaacutep d cagravei dt Nodejs trecircn Debian cabn
Wheezy Backport
Gii phaacutep nagravey CH cho Debian 7 dn gin lagrave chy don matilde di dacircy vi quyn root
$ echo deb httpftpusdebianorgdebian wheezy-backports main gtgt etcaptrarr˓sourceslist$ apt-get update
ETH cagravei dt Nodejs + NPM chy
$ apt-get install nodejs-legacy$ curl --insecure httpswwwnpmjsorginstallsh | bash
Noacute s cagravei dt mt phiecircn bn Nodejs ln hn 08 (vagraveo 29 thaacuteng 3 nam 2014 01021)
Tp hp t ngun
Gii phaacutep nagravey cho Debian 6 (Squeeze) vagrave hn d cagravei dt NodeJS chy don matilde sau vi quyn root
$ sudo apt-get install python g++ make checkinstall$ src=$(mktemp -d) ampamp cd $src$ wget -N httpnodejsorgdistnode-latesttargz$ tar xzvf node-latesttargz ampamp cd node-v$ configure$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -resrarr˓+node-v(+)$1p) make -j$(($(nproc)+1)) install$ sudo dpkg -i node_
Ly phiecircn bn mi nht qua DotDeb
Dotdeb lagrave mt kho cha caacutec goacutei d bin caacutec box Debian ca bn thagravenh mnh m n dnh vagrave LAMP dc cp nht
bull Nginx
bull PHP 54 vagrave 53 (Nhng trigravenh m rng PHP hu iacutech APC imagick Pinba xcache Xdebug XHpro)
bull MySQL 55
bull Percona toolkit
bull Redis
bull Zabbix
bull Passenger
Dotdeb h tr
bull Debian 60 ldquoSqueezeldquo vagrave 7 ldquoWheezyldquo
bull c 2 kin truacutec amd64 vagrave i386
11 Cagravei dt NodeBB theo HETHH 5
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
2 Contents
CHAPTER 1
Cagravei dt NodeBB
Cagravei dt NodeBB theo HETHH
Di dacircy lagrave hng dn tng bc d giuacutep bn cagravei dt vagrave chy
Ghi chuacute Nu h diu hagravenh ca bn khocircng coacute trong danh saacutech hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc cograven tt hnhatildey d trigravenh lecircn
Arch Linux
ETHu tiecircn chuacuteng ta cagravei dt goacutei phn mm c bn trc Hatildey thc hin pacman -Syu trc tiecircn d chc chaacuten rng bn datilde dng b vi kho vagrave ttc caacutec goacutei dc cp nht
$ sudo pacman -S git nodejs redis imagemagick
Nu bn mun s dng MongoDB LevelDB hoc mt nn tng c s d liu khaacutec ngoagravei Redis hatildey dc tagravei liu Cu higravenh c s d liu
Tip theo to bn sao ca kho sau
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc dc yecircu cu bi NodeBB
$ cd nodebb$ npm install
Bt du don matilde cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
3
NodeBB Documentation Release 041
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Ubuntu
ETHu tiecircn chuacuteng ta cagravei dt caacutec trigravenh nn
$ sudo apt-get install git nodejs redis-server imagemagick npm
Nu bn mun s dng MongoDB LevelDB hoc mt c s d liu khaacutec thay cho Redis xin dc Cu higravenh c s d liu
Nu trigravenh qun lyacute goacutei ca bn ch cagravei dt phiecircn bn Nodejs nh hn 08 (vd Ubuntu 1210 1304) dugraveng lnh lsquolsquonodendashversionlsquolsquo d xaacutec dnh phiecircn bn Nodejs ca bn
$ sudo add-apt-repository ppachris-leanodejs$ sudo apt-get update ampamp sudo apt-get dist-upgrade
Nu bn mun cagravei dt Nodejs v011 s dng url repo sau ppachris-leanodejs-devel
Sau doacute to bn sao repo
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc bi NodeBB
$ cd nodebb$ npm install
Thc hin cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Debian
Hng dn trecircn Ubuntu hin ti khocircng hoagraven toagraven tng thiacutech vi Debian vagrave coacute mt vagravei neacutet dc trng vagrave dc bit lagrave caacutech cagravei dt Nodejsvagrave caacutech ly dc bn mi nht ca Redis
Yecircu cu
NodeBB cn coacute caacutec phn mm sau dc cagravei dt
bull Nodejs iacutet nht lagrave bn 010 hoc cao hn
bull Redis bn 26 hoc cao hn
bull cURL ch cn thc hin lnh sudo apt-get install curl d cagravei dt
4 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Cagravei dt Nodejs
Debian 7 vagrave 6 hoc cu hn mc dnh khocircng coacute goacutei cagravei dt nodejs nhng coacute mt vagravei gii phaacutep d cagravei dt Nodejs trecircn Debian cabn
Wheezy Backport
Gii phaacutep nagravey CH cho Debian 7 dn gin lagrave chy don matilde di dacircy vi quyn root
$ echo deb httpftpusdebianorgdebian wheezy-backports main gtgt etcaptrarr˓sourceslist$ apt-get update
ETH cagravei dt Nodejs + NPM chy
$ apt-get install nodejs-legacy$ curl --insecure httpswwwnpmjsorginstallsh | bash
Noacute s cagravei dt mt phiecircn bn Nodejs ln hn 08 (vagraveo 29 thaacuteng 3 nam 2014 01021)
Tp hp t ngun
Gii phaacutep nagravey cho Debian 6 (Squeeze) vagrave hn d cagravei dt NodeJS chy don matilde sau vi quyn root
$ sudo apt-get install python g++ make checkinstall$ src=$(mktemp -d) ampamp cd $src$ wget -N httpnodejsorgdistnode-latesttargz$ tar xzvf node-latesttargz ampamp cd node-v$ configure$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -resrarr˓+node-v(+)$1p) make -j$(($(nproc)+1)) install$ sudo dpkg -i node_
Ly phiecircn bn mi nht qua DotDeb
Dotdeb lagrave mt kho cha caacutec goacutei d bin caacutec box Debian ca bn thagravenh mnh m n dnh vagrave LAMP dc cp nht
bull Nginx
bull PHP 54 vagrave 53 (Nhng trigravenh m rng PHP hu iacutech APC imagick Pinba xcache Xdebug XHpro)
bull MySQL 55
bull Percona toolkit
bull Redis
bull Zabbix
bull Passenger
Dotdeb h tr
bull Debian 60 ldquoSqueezeldquo vagrave 7 ldquoWheezyldquo
bull c 2 kin truacutec amd64 vagrave i386
11 Cagravei dt NodeBB theo HETHH 5
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 1
Cagravei dt NodeBB
Cagravei dt NodeBB theo HETHH
Di dacircy lagrave hng dn tng bc d giuacutep bn cagravei dt vagrave chy
Ghi chuacute Nu h diu hagravenh ca bn khocircng coacute trong danh saacutech hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc cograven tt hnhatildey d trigravenh lecircn
Arch Linux
ETHu tiecircn chuacuteng ta cagravei dt goacutei phn mm c bn trc Hatildey thc hin pacman -Syu trc tiecircn d chc chaacuten rng bn datilde dng b vi kho vagrave ttc caacutec goacutei dc cp nht
$ sudo pacman -S git nodejs redis imagemagick
Nu bn mun s dng MongoDB LevelDB hoc mt nn tng c s d liu khaacutec ngoagravei Redis hatildey dc tagravei liu Cu higravenh c s d liu
Tip theo to bn sao ca kho sau
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc dc yecircu cu bi NodeBB
$ cd nodebb$ npm install
Bt du don matilde cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
3
NodeBB Documentation Release 041
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Ubuntu
ETHu tiecircn chuacuteng ta cagravei dt caacutec trigravenh nn
$ sudo apt-get install git nodejs redis-server imagemagick npm
Nu bn mun s dng MongoDB LevelDB hoc mt c s d liu khaacutec thay cho Redis xin dc Cu higravenh c s d liu
Nu trigravenh qun lyacute goacutei ca bn ch cagravei dt phiecircn bn Nodejs nh hn 08 (vd Ubuntu 1210 1304) dugraveng lnh lsquolsquonodendashversionlsquolsquo d xaacutec dnh phiecircn bn Nodejs ca bn
$ sudo add-apt-repository ppachris-leanodejs$ sudo apt-get update ampamp sudo apt-get dist-upgrade
Nu bn mun cagravei dt Nodejs v011 s dng url repo sau ppachris-leanodejs-devel
Sau doacute to bn sao repo
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc bi NodeBB
$ cd nodebb$ npm install
Thc hin cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Debian
Hng dn trecircn Ubuntu hin ti khocircng hoagraven toagraven tng thiacutech vi Debian vagrave coacute mt vagravei neacutet dc trng vagrave dc bit lagrave caacutech cagravei dt Nodejsvagrave caacutech ly dc bn mi nht ca Redis
Yecircu cu
NodeBB cn coacute caacutec phn mm sau dc cagravei dt
bull Nodejs iacutet nht lagrave bn 010 hoc cao hn
bull Redis bn 26 hoc cao hn
bull cURL ch cn thc hin lnh sudo apt-get install curl d cagravei dt
4 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Cagravei dt Nodejs
Debian 7 vagrave 6 hoc cu hn mc dnh khocircng coacute goacutei cagravei dt nodejs nhng coacute mt vagravei gii phaacutep d cagravei dt Nodejs trecircn Debian cabn
Wheezy Backport
Gii phaacutep nagravey CH cho Debian 7 dn gin lagrave chy don matilde di dacircy vi quyn root
$ echo deb httpftpusdebianorgdebian wheezy-backports main gtgt etcaptrarr˓sourceslist$ apt-get update
ETH cagravei dt Nodejs + NPM chy
$ apt-get install nodejs-legacy$ curl --insecure httpswwwnpmjsorginstallsh | bash
Noacute s cagravei dt mt phiecircn bn Nodejs ln hn 08 (vagraveo 29 thaacuteng 3 nam 2014 01021)
Tp hp t ngun
Gii phaacutep nagravey cho Debian 6 (Squeeze) vagrave hn d cagravei dt NodeJS chy don matilde sau vi quyn root
$ sudo apt-get install python g++ make checkinstall$ src=$(mktemp -d) ampamp cd $src$ wget -N httpnodejsorgdistnode-latesttargz$ tar xzvf node-latesttargz ampamp cd node-v$ configure$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -resrarr˓+node-v(+)$1p) make -j$(($(nproc)+1)) install$ sudo dpkg -i node_
Ly phiecircn bn mi nht qua DotDeb
Dotdeb lagrave mt kho cha caacutec goacutei d bin caacutec box Debian ca bn thagravenh mnh m n dnh vagrave LAMP dc cp nht
bull Nginx
bull PHP 54 vagrave 53 (Nhng trigravenh m rng PHP hu iacutech APC imagick Pinba xcache Xdebug XHpro)
bull MySQL 55
bull Percona toolkit
bull Redis
bull Zabbix
bull Passenger
Dotdeb h tr
bull Debian 60 ldquoSqueezeldquo vagrave 7 ldquoWheezyldquo
bull c 2 kin truacutec amd64 vagrave i386
11 Cagravei dt NodeBB theo HETHH 5
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Ubuntu
ETHu tiecircn chuacuteng ta cagravei dt caacutec trigravenh nn
$ sudo apt-get install git nodejs redis-server imagemagick npm
Nu bn mun s dng MongoDB LevelDB hoc mt c s d liu khaacutec thay cho Redis xin dc Cu higravenh c s d liu
Nu trigravenh qun lyacute goacutei ca bn ch cagravei dt phiecircn bn Nodejs nh hn 08 (vd Ubuntu 1210 1304) dugraveng lnh lsquolsquonodendashversionlsquolsquo d xaacutec dnh phiecircn bn Nodejs ca bn
$ sudo add-apt-repository ppachris-leanodejs$ sudo apt-get update ampamp sudo apt-get dist-upgrade
Nu bn mun cagravei dt Nodejs v011 s dng url repo sau ppachris-leanodejs-devel
Sau doacute to bn sao repo
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Cagravei dt caacutec trigravenh ph thuc bi NodeBB
$ cd nodebb$ npm install
Thc hin cagravei dt bng caacutech chy ng dng vi th setup
$ nodebb setup
Mc dnh cagravei dt lagrave cho maacutey ch ni da vagrave chy trecircn cng mc dnh vi redis lu tr trecircn cugraveng mt maacuteycng
Cui cugraveng ta chy din dagraven
$ nodebb start
NodeBB cung coacute th khi dng vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ETHc thecircm v caacutec tugravey chn dacircy
Debian
Hng dn trecircn Ubuntu hin ti khocircng hoagraven toagraven tng thiacutech vi Debian vagrave coacute mt vagravei neacutet dc trng vagrave dc bit lagrave caacutech cagravei dt Nodejsvagrave caacutech ly dc bn mi nht ca Redis
Yecircu cu
NodeBB cn coacute caacutec phn mm sau dc cagravei dt
bull Nodejs iacutet nht lagrave bn 010 hoc cao hn
bull Redis bn 26 hoc cao hn
bull cURL ch cn thc hin lnh sudo apt-get install curl d cagravei dt
4 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Cagravei dt Nodejs
Debian 7 vagrave 6 hoc cu hn mc dnh khocircng coacute goacutei cagravei dt nodejs nhng coacute mt vagravei gii phaacutep d cagravei dt Nodejs trecircn Debian cabn
Wheezy Backport
Gii phaacutep nagravey CH cho Debian 7 dn gin lagrave chy don matilde di dacircy vi quyn root
$ echo deb httpftpusdebianorgdebian wheezy-backports main gtgt etcaptrarr˓sourceslist$ apt-get update
ETH cagravei dt Nodejs + NPM chy
$ apt-get install nodejs-legacy$ curl --insecure httpswwwnpmjsorginstallsh | bash
Noacute s cagravei dt mt phiecircn bn Nodejs ln hn 08 (vagraveo 29 thaacuteng 3 nam 2014 01021)
Tp hp t ngun
Gii phaacutep nagravey cho Debian 6 (Squeeze) vagrave hn d cagravei dt NodeJS chy don matilde sau vi quyn root
$ sudo apt-get install python g++ make checkinstall$ src=$(mktemp -d) ampamp cd $src$ wget -N httpnodejsorgdistnode-latesttargz$ tar xzvf node-latesttargz ampamp cd node-v$ configure$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -resrarr˓+node-v(+)$1p) make -j$(($(nproc)+1)) install$ sudo dpkg -i node_
Ly phiecircn bn mi nht qua DotDeb
Dotdeb lagrave mt kho cha caacutec goacutei d bin caacutec box Debian ca bn thagravenh mnh m n dnh vagrave LAMP dc cp nht
bull Nginx
bull PHP 54 vagrave 53 (Nhng trigravenh m rng PHP hu iacutech APC imagick Pinba xcache Xdebug XHpro)
bull MySQL 55
bull Percona toolkit
bull Redis
bull Zabbix
bull Passenger
Dotdeb h tr
bull Debian 60 ldquoSqueezeldquo vagrave 7 ldquoWheezyldquo
bull c 2 kin truacutec amd64 vagrave i386
11 Cagravei dt NodeBB theo HETHH 5
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Cagravei dt Nodejs
Debian 7 vagrave 6 hoc cu hn mc dnh khocircng coacute goacutei cagravei dt nodejs nhng coacute mt vagravei gii phaacutep d cagravei dt Nodejs trecircn Debian cabn
Wheezy Backport
Gii phaacutep nagravey CH cho Debian 7 dn gin lagrave chy don matilde di dacircy vi quyn root
$ echo deb httpftpusdebianorgdebian wheezy-backports main gtgt etcaptrarr˓sourceslist$ apt-get update
ETH cagravei dt Nodejs + NPM chy
$ apt-get install nodejs-legacy$ curl --insecure httpswwwnpmjsorginstallsh | bash
Noacute s cagravei dt mt phiecircn bn Nodejs ln hn 08 (vagraveo 29 thaacuteng 3 nam 2014 01021)
Tp hp t ngun
Gii phaacutep nagravey cho Debian 6 (Squeeze) vagrave hn d cagravei dt NodeJS chy don matilde sau vi quyn root
$ sudo apt-get install python g++ make checkinstall$ src=$(mktemp -d) ampamp cd $src$ wget -N httpnodejsorgdistnode-latesttargz$ tar xzvf node-latesttargz ampamp cd node-v$ configure$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -resrarr˓+node-v(+)$1p) make -j$(($(nproc)+1)) install$ sudo dpkg -i node_
Ly phiecircn bn mi nht qua DotDeb
Dotdeb lagrave mt kho cha caacutec goacutei d bin caacutec box Debian ca bn thagravenh mnh m n dnh vagrave LAMP dc cp nht
bull Nginx
bull PHP 54 vagrave 53 (Nhng trigravenh m rng PHP hu iacutech APC imagick Pinba xcache Xdebug XHpro)
bull MySQL 55
bull Percona toolkit
bull Redis
bull Zabbix
bull Passenger
Dotdeb h tr
bull Debian 60 ldquoSqueezeldquo vagrave 7 ldquoWheezyldquo
bull c 2 kin truacutec amd64 vagrave i386
11 Cagravei dt NodeBB theo HETHH 5
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Debian 7 (Wheezy)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg wheezy all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg wheezy all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Debian 6 (Squeeze)
ETH coacute mt kho DotDeb dy d
$ sudo echo deb httppackagesdotdeborg squeeze all gtgt etcaptsourceslist$ sudo echo deb-src httppackagesdotdeborg squeeze all gtgt etcaptsourceslist
Sau doacute thecircm khoacutea GPC sau
$ wget httpwwwdotdeborgdotdebgpg$ sudo apt-key add dotdebgpg
Vagrave cp nht ngun
$ sudo apt-get update
Cagravei dt NodeBB
Bacircy gi ta datilde coacute NodeJS vagrave Redis dc cagravei dt chy lnh sau d cagravei dt goacutei phn mm nn
$ apt-get install redis-server imagemagick git
Tip theo to bn sao ca kho sau
$ cd pathtonodebbinstalllocation$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
Chuacuteng ta s tin hagravenh cagravei dt caacutec trigravenh ph thuc cho NodeBB qua NPM
$ cd pathtonodebbinstalllocationnodebb (hoc nu bn dang dng dn cagravei dt run cdrarr˓nodebb)$ npm install
Cagravei dt NodeBB bng caacutech chy ng dng vi th ndashsetup
$ nodebb setup
1 URL of this installation lagrave da ch IP hoc tecircn min tr v IP doacute
6 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Viacute d http0000 hoc httpexampleorg
2 Port number of your NodeBB lagrave cng d coacute th truy cp vagraveo trang Chuacute yacute Nu bn khocircng to proxy chocng ca bn vi mt gii phaacutep nagraveo doacute nh Nginx thigrave necircn s dng cng 80
3 Nu bn datilde thc hin caacutec bc trecircn d cagravei dt redis-server thigrave s dng giaacute tr cagravei dt mc dnh lagrave redis
Vagrave sau cugraveng hatildey bt du chy NodeBB
$ nodebb start
Chuacute yacute Nu NodeBB hoc maacutey ch ca bn gp s c NodeBB s khocircng khi docircng li dacircy lagrave lyacute do ti sao bn necircn dc qua caacutec caacutechkhaacutec d khi dng NodeBB vi caacutec trigravenh tr giuacutep nh supervisor vagrave forever ch cn dc dacircy dn gin nh 1 cuacute nhp chut
Ph lc th thut vagrave li khuyecircn
Bn necircn bo mt cagravei dt NodeBB ca bn dc thecircm dacircy
Bn necircn s dng Nginx (hoc tng t) d to proxy cho NodeBB v cng 80 dc thecircm dacircy
SmartOS
Yecircu cu
NodeBB cn coacute nhng chng trigravenh nagravey dc cagravei dt
bull Nodejs (phiecircn bn 010 hoc hn hng dn di)
bull Redis (phiecircn bn 26 hoc hn hng dn di) hoc MongoDB (phiecircn bn 26 hoc hn)
bull nginx (phiecircn bn 1313 hoc hn ch khi bn coacute yacute dnh s dng nginx to proxy cho NodeBB)
Truy cp maacutey ch
1 ETHang nhp vagraveo tagravei khon Joyent ca bn Joyentcom
2 Chn Create Instance
3 To image smartos nodejs mi nht
Chuacute yacute Nhng bc nagravey datilde dc th nghim vi image smartos nodejs 1310 smartos nodejs1323
4 ETHi phiecircn bn ca bn hin Running sau doacute click chn tecircn ca noacute
5 Tigravem Login vagrave mt khu qun tr Nu khu vc Credentials b thiu hatildey ti li trang
Viacute d ssh root0000 ACac13
6 Truy cp SSH theo quyn admin khocircng root ssh admin0000
Chuacute yacute ETHi vi nhng ngi dugraveng Windows cha coacute cagravei dt SSH thigrave dacircy lagrave 1 tugravey chn Cygwincom
Cagravei dt
1 Cagravei dt trigravenh ph thuc cho NodeBB
11 Cagravei dt NodeBB theo HETHH 7
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
$ sudo pkgin update$ sudo pkgin install scmgit nodejs build-essential ImageMagick redis
Nu mt trong s dograveng trecircn tht bi thigrave chy lecircnh di
$ pkgin search failed-name$ sudo pkgin install available-name
2 Nu cn cagravei dt redis-server vi mc dnh lagrave service (t dng khi dng vagrave khi dng li)
Nu bn mun s dng MongoDB LevelDB hoc 1 c s d liu khaacutec ngoagravei Redis thigrave hatildey dc Cu higravenh c s d liu
Chuacute yacute Nhng bc nagravey d cagravei dt nhanh 1 server redis nhng khocircng ti u d dugraveng chiacutenh thc
Chuacute yacute Nu bn datilde chy redis-server ri thigrave hatildey thoaacutet khi noacute ngay
$ svcadm enable redis$ svcs svcpkgsrcredisdefault
Chuacute yacute Nu STATE lagrave maintenance thigrave
$ scvadm clear redis
- ETH tt redis-server vagrave ngan noacute khi dng li
$ scvadm disable redis
- ETH khi dng redis-server vagrave cho noacute luocircn chy
$ scvadm enable redis
3 Chuyn dn ni magrave bn mun to folder cagravei dt nodebb
$ cd parentdirectoryofnodebb
4 To bn sao NodeBBrsquos repository (bn coacute h di nodebb cui thagravenh tecircn folder khaacutec magrave bn mun)
$ git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
5 Cagravei dt trigravenh ph thuc npm ca NodeBB
$ cd nodebb$ npm install
6 Chy matilde cagravei dt NodeBB
$ nodebb setup
(a) URL used to access this NodeBB lagrave da ch ip bn dugraveng d dang nhp SSH hoc tecircn mintr dn IP nagravey
Viacute d http0000 hoc httpexampleorg
(b) Port number of your NodeBB lagrave cng cn d truy cp dn trang ca bn
Chuacute yacute Nu bn khocircng s dng nginx hoc 1 server web nagraveo khaacutec d to proxy thigrave necircn d cng80
(c) Please enter a NodeBB secret - Khocircng gi email vagrave cocircng khai matilde nagravey
8 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
(d) IP or Hostname to bind to - S dng giaacute tr mc dnh tr khi maacutey ch bn coacute yecircu cu khaacutec
(e) Nu bn s dng caacutec bc cagravei dt redis-server trecircn thigrave hatildey s dng giaacute tr cagravei dt mc dnh cho redis
7 Khi dng tin trigravenh NodeBB th cocircng Chuacute yacute ETHiu nagravey khocircng necircn s dng cho bn chiacutenh thc nhng thay vigrave s dngdaemon thigrave necircn s dng Forever hoc Supervisor ETHc caacutec tugravey chnh dacircy
$ node app
8 Truy cp ng dng ca bn Viacute d Vi cng lagrave 4567 http00004567 or httpexampleorg4567
Chuacute yacute Vi cng lagrave 80 thigrave 80 khocircng cn phi nhp
Chuacute yacute Nu hng dn trecircn khocircng rotilde ragraveng vi bn hoc nu bn coacute gp rc ri gigrave hatildey cho chuacuteng tocirci bit bng caacutech baacuteo caacuteo li ti dacircy
Cp nht NodeBB
Chuacute yacute Chi tit v vic cp nht NodeBB xin dc Cp nht NodeBB
Windows 8
Phn mm yecircu cu
ETHu tiecircn cagravei dt caacutec chng trigravenh di dacircy
bull httpswindowsgithubcom
bull httpnodejsorg
bull httpsourceforgenetprojectsredisfilesredis-2610
bull httpimagemagickorgscriptbinary-releasesphpwindows
Bn coacute th phi khi dng li maacutey tiacutenh ca migravenh
Chy NodeBB
Khi dng Redis Server
Ghi chuacute The default location of Redis Server is
CProgram Files (x86)RedisStartRedisServercmd
M Git Shell vagrave daacutenh dograveng lnh sau To bn sao NodeBB repo
git clone -b v05x httpsgithubcomNodeBBNodeBBgit
Truy cp dng dn
cd NodeBB
Cagravei dt trigravenh ph thuc
npm install
11 Cagravei dt NodeBB theo HETHH 9
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Chy trigravenh tng taacutec cagravei dt
node appjs
Bn coacute th d mi tugravey chn lagrave mc dnh
Vagrave bn datilde xong Sau khi cagravei dt chy
node appjs
Bn coacute th truy cp din dagraven ti http1270014567
Phaacutet trin trecircn Windows
S coacute docirci chuacutet khoacute chu khi phi tt vagrave khi dng li NodeBB mi khi bn thay di Hatildey cagravei dt supervisor
npm install -g supervisor
M bash
bash
Vagrave chy NodeBB trong ch d ldquowatchrdquo
nodebb watch
Noacute s bt NodeBB trong ch d nhagrave phaacutet trin vagrave s theo dotildei caacutec file dc thay di vagrave t dng khi dng li din dagraven
bull Arch Linux
bull Ubuntu
bull Debian
bull SmartOS
bull Windows
bull CentOS (external)
Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud)
Di dacircy lagrave hng dn tng bc d bn cagravei dt vagrave chy trecircn caacutec gii phaacutep PaaS
Ghi chuacute Nu gii phaacutep PaaS ca bn khocircng coacute trong danh saacutech hatildey hatildey da ra yecircu cu trecircn cng dng ca chuacuteng tocirci hoc thmchiacute tt hn hatildey d trigravenh lecircn
Cloud 9 IDE
Hng dn cagravei dt di dacircy dagravenh cho IDE nn web Cloud 9
Bc 1 To bn sao NodeBB vagraveo workspace ca bn t GitHub Bn coacute th s dng lnh sau t terminal
git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb
10 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Lnh nodebb sau git url s to 1 file tecircn lagrave nodebb vigrave vy bn phi CD vagraveo trong file doacute sau khi bn to xong bn sao ca NodeBB
Bc 2 Cagravei dt redis vi Cloud9rsquos package manager
nada-nix install redis
Bc 3 Chy redis server ti cng 16379 - cng 6379 datilde dc s dng bi Cloud 9 ldquoamprdquo d dograveng lnh thc hin nn Bn coacute th hy tintrigravenh bt c luacutec nagraveo sau nagravey $IP lagrave bin h thng ca Cloud 9 cha da ch IP instance ca bn
redis-server --port 16379 --bind $IP amp
Bc 4 Xaacutec dnh da ch IP instance ca bn d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave 1 trong nhng yecircu cu ca Cloud 9 vagrave coacute vnh lagrave caacutech duy nht mi lagravem noacute chy Bn khocircng th s dng $IP trong file configjson (coacute nghıa lagrave bn khocircng th nhp $IP trongnode app ndashsetup)
echo $IP
Bc 5 Cagravei NodeBB vagrave trigravenh ph thuc
npm install
Bc 6 Chy trigravenh cagravei dt nodebb
node app --setup
URL ca phn cagravei dt nagravey necircn lagrave lsquohttpworkspace_name-c9-usernamec9iolsquo thay th workspace_name bng tecircnworkspace ca bn vagrave username vi username ca bn Chuacute yacute rng NodeBB vn dang s dng kt ni khocircng bo mt http d tijQuery bn s thy d s dng http hn nhiu thay vigrave https cho url nn ca bn Nu khocircng jQuery s khocircng ti vagrave NodeBB skhocircng chy
S cng khocircng thc s quan trng - Cloud9 s bt bn s dng cng 80 Hatildey dt noacute lagrave 80 Nu noacute lagrave cng khaacutec nh 4567 cung vn sbigravenh thng
Use a port number to access NodeBB Li ln na noacute cung khocircng quaacute khaacutec bit Hatildey dt lagrave ldquonordquo Hoc khaacutec cung vn dc
Host IP or address of your Redis instance localhost (giaacute tr xut ra ca lnh $IP cung dc chp nhn)
IP or Hostname to bind to Nhp giaacute tr magrave $IP cha Bc 4 Noacute s coacute th ging nh sau 12345678
Host port of your Redis instance 16379
Redis Password Tr khi bn cagravei dt noacute th cocircng khocircng thigrave Redis s dc cu higravenh khocircng coacute mt khu Hatildey d trng vagrave nhn Enter
Ln cagravei dt du tiecircn yecircu cu cn coacute Admin name email address vagrave password dc dt
Vy lagrave xong ETHng s dng nuacutet Run trecircn cugraveng ca IDE noacute thng coacute li di vi tocirci Bn necircn s dng command line thigrave tt hn Chylnh sau
node app
Sau doacute truy cp httpworkspace_name-c9-usernamec9io ti trigravenh duyt
Khc phc
Vn d thng gp lagrave dch v c s d liu cha dc khi dng Hatildey chc chn bn datilde cagravei dt Redis 1 caacutech chiacutenh xaacutec vagrave chy
redis-server --port 16379 --bind $IP
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 11
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Heroku
Chuacute yacute Cagravei dt lecircn Heroku yecircu cu maacutey local phi chy 1 phiecircn bn unix NodeBB khocircng chy trecircn Windows
1 Ti vagrave cagravei dt Heroku Toolbelt cho h diu hagravenh ca bn
2 ETHang nhp vagraveo tagravei khon Heroku heroku login
3 Xaacutec nhn tagravei khon Heroku bng caacutech thecircm th credit (ti httpherokucomverify)
4 To bn sao repository git clone -b v05x httpsgithubcomNodeBBNodeBBgit pathtorepoclone
5 cd pathtorepoclone
6 Cagravei dt dependencies npm install
7 To heroku app heroku create
8 Bt WebSocket (beta) heroku labsenable websockets -a APP_NAME APP_NAME dc cungcp bi Heroku vagrave ging nh sau adjective-noun-wxyzherokuappcom (Chuacute yacute ETHc tagravei liu sau) bherokuappcom khi nhp APP_NAME phiacutea trecircn
9 Bt Redis To Go cho tagravei khon heroku ca bn heroku addonsadd redistogonano
10 Chy matilde cagravei dt NodeBB node app --setup (thocircng tin v Heroku server vagrave Redis to Go instance coacute th tigravemthy trang tagravei khon ca bn)
bull Tecircn server ca bn nm trong trang cagravei dt Heroku app vagrave ging nh sau adjective-noun-wxyzherokuappcom
bull S dng bt c cng nagraveo noacute s b b qua
bull Redis server coacute th tigravem trong redis url Viacute d vi url lagrave redisredistogoh28h3wgh37fns7crestfishredistogocom12345
bull Server lagrave fishyfishredistogocom
bull Cng lagrave 12345
bull Mt khu lagrave h28h3wgh37fns7
12 Thecircm 3 goacutei sau vagraveo phn dependencies trong file packagejson
dependencies nodebb-plugin-dbsearch 0010redis ~0101connect-redis ~200
devDependencies
13 To 1 Procfile cho Heroku echo web node loaderjs gt Procfile
14 Commit Procfile
git add -f Procfile configjson packagejson ampamp git commit -am adding Procfile andrarr˓configs for Heroku
15 Push lecircn heroku git push heroku master Hatildey chc chn rng khoacutea SSH duacuteng datilde dc thecircm vagraveo tagravei khonca bn nu khocircng thigrave push s khocircng thagravenh cocircng
16 Khi to 1 dyno heroku psscale web=1
17 Truy cp vagraveo ng dng
12 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo
Luocircn cp nht
Nu bn mun pull nhng thay di mi nht t git repository vagraveo ng dng Heroku ca bn
1 Chuyn hng repository ti pathtonodebb
2 git pull
3 npm install
4 node app --upgrade
5 git commit -am upgrading to latest nodebb
6 git push heroku master
NitrousIO
Hng dn cagravei dt di dacircy dagravenh cho NitrousIO lthttpnitrousiogt
Bc 1 To ng dng mi vi NodeJS
httpswwwnitrousioappboxesnew
Bc 2 M terminal SSH vagraveo ng dng M IDE
Bc 3 Ly file ca NodeBB v unzip xoacutea masterzip vagrave cd vagraveo folder
wget httpsgithubcomNodeBBNodeBBarchivev05xzip ampamp unzip NodeBB-v05xzip ampamprarr˓ rm NodeBB-v05xzip ampamp cd NodeBB-v05x
Bc 4 NPM Install
npm install
Bc 5 Cagravei dt Redis
parts install redis
Bc 6 Cagravei dt NodeBB
nodebb setup
ETH mi th lagrave mc dnh nhng bn vn coacute th t thay di
Tocirci d ngh necircn dugraveng cng 8080
Bc 14 Vagrave cui cugraveng khi dng NodeBB
nodebb start
Vagrave sao doacute m ldquoPreview URIrdquo khocircng coacute cng nu bn datilde dt cng lagrave 8080
Chuacute yacute
Bn coacute th m rng tagravei nguyecircn ca ng dng httpwwwnitrousioappn2obonus
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 13
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Openshift Paas
Hng dn di dacircy dagravenh cho Openshift lthttpopenshiftcomgt Paas
Bc 1 To ng dng mi
rhc app create nodebb nodejs-010
Bc 2 Thecircm cartridge Redis
rhc add-cartridge httpcartreflect-claytondevrhcloudcomreflectrarr˓github=smarterclaytonopenshift-redis-cart -a nodebb
Bc 3 SSH dn ng dng ca bn
rhc app ssh -a nodebb
Bc 4 Xaacutec dnh ip ca NodeJS vagrave Redis d NodeBB coacute th chy chiacutenh xaacutec ETHacircy lagrave mt yecircu cu ca Openshift vagrave lagrave caacutech duy nhtd noacute chy Bn khocircng th s dng $IP trong configjson (Coacute nghıa lagrave bn khocircng th nhp $IP trong lnh node app ndashsetup) Dogravengdu tiecircn NodeJS vagrave dograveng th hai Redis Giaacute tr xut ra ca lnh echo $REDIS_CLI s nh sau -h ip_redis -p port_redis -apassword
echo $OPENSHIFT_NODEJS_IP ampamp echo $REDIS_CLI
Bc 5 Thoaacutet SSH
Bc 6 Thecircm matilde ngun ca NodeBB vagraveo repository ca ng dng
cd nodebb ampamp git remote add upstream -m master httpsgithubcomNodeBBNodeBBgit
Bc 7 Ly file v vagrave push
git pull -s recursive -X theirs upstream v05x ampamp git push
Bc 8 Ngng chy ng dng
rhc app stop -a nodebb
Bc 9 SSH vagraveo ng dng
rhc app ssh -a nodebb
Bc 10 Sa mocirci trng chy ca NodeJS trong terminal vi SSH
cd ~nodejsconfiguration ampamp nano nodeenv
Bc 11 Thay serverjs bng appjs vagrave thoaacutet khi editor
ctrl + x
Bc 12 Trong terminal khaacutec bt du chy ng dng
rhc app start -a nodebb
Bc 13 Chy matilde cagravei dt NodeBB trecircn terminal vi SSH
cd ~app-rootrepo ampamp node app --setup
14 Chapter 1 Cagravei dt NodeBB
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
URL d cagravei dt necircn dt lagrave lsquohttpnodebb-usernamerhcloudcomlsquo thay username vi username ca bn
Port number 8080
IP or Hostname to bind to Nhp giaacute tr xut ca $OPENSHIFT_NODEJS_IP trong Bc 4
Host IP or address of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Host port of your MongoDB instance Nhp giaacute tr xut ca $REDIS_CLI trong bc Bc 4
Redis Password Nhp giaacute tr xut ca $REDIS_CLI trong Bc 4
Bc 14 Vagrave cui cugraveng trong terminal khaacutec khi dng li ng dng
rhc app restart -a nodebb
Vagrave sau doacute truy cp httpnodebb-usernamerhcloudcom trong trigravenh duyt
Chuacute yacute
Restart NodeBB trong trang Admin khocircng hot dng S dng
rhc app restart -a nodebb
Koding
Chuacute yacute Vic cagravei dt trecircn Koding cn coacute tagravei khon min phiacute trecircn Kodingcom
1 To tagravei khon hoc dang nhp vagraveo Kodingcom lthttpkodingcomgt
2 Nhn vagraveo nuacutet magraveu xanh laacute trocircng nh sau gt_
3 Bn s nhigraven thy VM ca bn vi ch Off becircn phi magraveu d hatildey nhn vagraveo doacute d bt VM
4 Nhn tip vagraveo noacute khi coacute thocircng baacuteo Ready
5 Bacircy gi bn dang trong ca s terminal Vic cagravei dt gn ging vi Ubuntu nhng hi khaacutec mt chuacutet vigrave mt s goacutei datilde dc cagravei dtsn
6 ETHu tiecircn ta phi chc chn rng mi th datilde dc cp nht - sudo apt-get update ampamp sudo apt-get upgrade
7 Nhp vagraveo mt khu magrave bn datilde dang kyacute nu bn dang kyacute bng Github hoc qua 1 becircn th ba nagraveo khaacutec bn phi cagravei dt 1 caacuteitrong trang cagravei dt tagravei khon Sau doacute quay tr li
8 Bacircy gi chy lnh sau sudo apt-get install python-software-properties python g++make
9 Cagravei dt goacutei h tr - sudo apt-get install redis-server imagemagick
10 Tip to bn sao NodeBB vagraveo trong NodeBB folder - git clone -b v05x httpsgithubcomNodeBBNodeBBgit nodebb (Tugravey chn Thay th nodebb cui nu bn mun coacute tecircn folder khaacutec)
11 Truy cp vagraveo NodeBB folder - cd nodebb (tr khi bn datilde dt tecircn folder khaacutec bc trc vagrave nu bn datilde quecircn tecircn folderchay ls d nhigraven thy tecircn ca folder)
12 Bacircy gi chuacuteng ta cagravei dt caacutec trigravenh ph thuc ca NodeBB - npm install (coacute th mt 1 dn 2 phuacutet)
13 Cagravei dt nodebb bng dograveng lnh - nodebb setup
14 Cacircu hi du tiecircn s hi tecircn min ca bn dng d noacute lagrave localhost Tecircn min ca bn s nh sau httpyourkodingusernamekdio - Username ca bn coacute th nhigraven thy goacutec trecircn cugraveng becircn phi
12 Cagravei dt NodeBB trecircn dch v din toaacuten daacutem may (Cloud) 15
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
15 Hoagraven tt vic cagravei dt (giaacute tr mc dnh sau khi cagravei dt tecircn min du coacute th chp nhn hatildey n enter cho dn khi coacute yecircu cu ldquoCreatean Adminrdquo
16 To username vagrave mt khu admin sau doacute noacute s to caacutec categories vagrave mt vagravei th khaacutec magrave lagravem NodeBB tuyt vi
17 Gi chuacuteng ta coacute th chy NodeBB - nodebb start
18 M tab khaacutec trecircn trigravenh duyt vagrave truy cp vagraveo da ch httpyourkodingusernamekdio4567 (nu nhbn khocircng thay di cng mc dnh trong phn cagravei dt)
19 Bn s nhigraven thy 1 magraven higravenh d tip tc truy cp vagraveo trang ca bn nhn vagraveo link na becircn di d tip tc truy cp trang
Chuacutec mng bn datilde cagravei dt thagravenh cocircng NodeBB trecircn Kodingcom
Nu hng dn trecircn khocircng rotilde ragraveng hoc bn gp rc ri hatildey cho chuacuteng tocirci bit bng caacutech to baacuteo caacuteo (Hatildey tag a5mith trongissue ca bn vigrave tocirci datilde vit hng dn nagravey)
Mt vagravei vn d khi chy trecircn Koding
Vigrave Koding lagrave min phiacute necircn noacute s coacute 1 vagravei sc thaacutei ca host cloud
1 VM s t dng tt sau 15 phuacutet khocircng coacute hot dng ETHiu nagravey khocircng may lagrave khocircng aacutem ch trang web magrave lagrave ca s Terminal(Bn coacute th khc phc diu nagravey bng caacutech luocircn m terminal vagrave chy lnh ls mi 10 phuacutet d lagravem mi li b dm)
2 Thnh thong bn s nhn dc thocircng baacuteo rng ldquoYour VM is unavailable try again laterrdquo bn coacute th th dang xut vagrave dangnhp li ti li trang hoc baacuteo caacuteo li vi di h tr ca h
3 Kodingcom s dng ubuntu d host VM vigrave vy hiu bit can bn v Unbuntu s coacute iacutech
bull Cloud9
bull Heroku
bull NitrousIO
bull Openshift
bull Digital Ocean (external)
bull Kodingcom
bull Codio (external)
16 Chapter 1 Cagravei dt NodeBB
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 2
Cu higravenh NodeBB
Configuring Databases
NodeBB has a Database Abstraction Layer (DBAL) that allows one to write drivers for their database of choiceCurrently we have the following options
MongoDB
If yoursquore afraid of running out of memory by using Redis or want your forum to be more easily scalable you caninstall NodeBB with MongoDB This tutorial assumes you know how to SSH into your server and have root access
These instructions are for Ubuntu Adjust them accordingly for your distro
Note If you have to add sudo to any command do so No one is going to hold it against you )
Step 1 Install MongoDB
The latest and greatest MongoDB is required (or at least greater than the package manager) The instructions to installit can be found on the MongoDB manual)
Step 2 Install nodejs
Like MongoDB the latest and greatest nodejs is required (or at least greater than the package manager) so Irsquom leavingthis to the official wiki The instructions to install can be found on Joyent
Note NPM is installed along with nodejs so there is no need to install it separately
Step 3 Install the Base Software Stack
Enter the following into the terminal to install the base software required to run NodeBB
17
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
apt-get install git build-essential imagemagick
Step 4 Clone the Repository
Enter the following into the terminal replacing pathtonodebbinstalllocation to where you would like NodeBB tobe installed
$ cd pathtonodebbinstalllocation$ git clone gitgithubcomNodeBBNodeBBgit nodebb
Step 5 Install The Required NodeBB Dependencies
Go into the newly created nodebb directory and install the required dependencies by entering the following
$ cd nodebb$ npm install
Step 6 Adding a New Database With Users
To go into the MongoDB command line type
$ mongo
To add a new database called nodebb type
gt use nodebb
To add a user to access the nodebb database type
For MongoDB 26x
gt dbcreateUser( user nodebb pwd ltEnter in a secure passwordgt roles [rarr˓readWrite ] )
Note NodeBB requires MongoDB 260 or higher The role readWrite provides read or write any collection withina specific database to user
Step 7 Configure MongoDB
Modify etcmongodbconf
nano etcmongodbconf
To enable authentication uncomment auth = true Restart MongoDB
service mongodb restart
18 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Step 8 Configuring NodeBB
Make sure you are in your NodeBB root folder If not just type
$ cd pathtonodebb
To setup the app type
$ node app --setup
bull Change the hostname to your domain name
bull Accept the defaults by pressing enter until it asks you what database you want to use Type mongo in that field
bull Accept the default port unless you changed it in the previous steps
bull Change your username to nodebb unless you set it to another username
bull Enter in the password you made in step 5
bull Change the database to nodebb unless you named it something else
Continue with the installation following the instructions the installer provides you
Step 9 Starting the App
To start the app run
$ nodebb start
Now visit yourdomainoripcom4567 and your NodeBB installation should be running
NodeBB can also be started with helper programs such as supervisor or forever You can also use nginx as a reverseproxy)
LevelDB
Follow the installation instructions for your particular OS but feel free to omit the Redis installation
After cloning NodeBB ensure that you run
npm install levelup leveldown
Finally set up a directory to store your LevelDB database for example
mkdir varlevel
Run the NodeBB install select level when it prompts you for your database If you created the folder as above youcan leave the rest of the questions as default
bull Redis (default see installation guides)
bull Mongo
bull Level
Ghi chuacute If you would like to write your own database driver for NodeBB please visit our community forum and wecan point you in the right direction
21 Configuring Databases 19
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Running a Secondary Database
Cnh baacuteo This option is experimental and should not be used on a production environment
Both databases must be flushed before beginning - there isnrsquot a mechanism yet that detects an existing installationon one database but not another Until fail-safersquos such as these are implemented this option is hidden under the--advanced setup flag
node app --setup --advanced
Consult the other database guides for instructions on how to set up each specific database Once you select a secondarydatabasersquos modules therersquos no turning back - until somebody writes an exporterimporter
Currently this setup is being tested with Redis as the primary store (sets lists and sorted sets because Redis is superfast with these) and Mongo as the hash store (post and user data because ideally we wouldnrsquot want this in RAM)
Configuring Web Server Proxies
Here a few options that you can use to proxy your NodeBB forum
Configuring nginx as a proxy
NodeBB by default runs on port 4567 meaning that builds are usually accessed using a port number in addition totheir hostname
httpexampleorg4567
In order to allow NodeBB to be served without a port nginx can be set up to proxy all requests to a particular hostname(or subdomain) to an upstream NodeBB build running on any port
Requirements
bull NGINX version v1313 or greater
ndash Package managers may not provide a new enough version To get the latest version compile it your-self or if on Ubuntu use the NGINX Stable or NGINX Development PPA builds if you are onDebian use DotDeb repository to get the latest version of Nginx
ndash To determine your nginx version execute nginx -V in a shell
Configuration
NGINX-served sites are contained in a server block This block of options goes in a specific place based on hownginx was installed and configured
bull pathtonginxsites-available ndash files here must be aliased to sites-enabled
bull pathtonginxconfdconf ndash filenames must end in conf
bull pathtonginxhttpdconf ndash if all else fails
Below is the basic nginx configuration for a NodeBB build running on port 4567
20 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
server listen 80
server_name forumexampleorg
location proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header Host $http_hostproxy_set_header X-NginX-Proxy true
proxy_pass http1270014567proxy_redirect off
SocketIO Supportproxy_http_version 11proxy_set_header Upgrade $http_upgradeproxy_set_header Connection upgrade
Notes
bull Remember to also edit configjson and change use_port from true to false
bull nginx must be on version 14x to properly support websockets DebianUbuntu use 12 although it will workthere will be a reduction in functionality
bull The proxy_pass IP should be 127001 if your NodeBB is hosted on the same physical server as yournginx server Update the port to match your NodeBB if necessary
bull This config sets up your nginx server to listen to requests for forumexampleorg It doesnrsquot magicallyroute the internet to it though so you also have to update your DNS server to send requests for forumexampleorg to the machine with nginx on it
Configuring apache as a proxy
Prerequisites to making this work Apache 24x
What if Irsquom on 22x (DebianUbuntu)
you need to manually compile and add the module ldquomod_proxy_wstunnelrdquo to the Apache 22 branch If yoursquore runningUbuntu or Debian yoursquore likely on the 22 branch of code
The following guide will assist with that if yoursquore on Debian or Ubuntu This is what I used to backport themod_proxy_wstunnel module to the 22 code base of Apache
httpwwwamossmeuk201306apache-2-2-websocket-proxying-ubuntu-mod_proxy_wstunnel
NOTE On ubuntu if yoursquore missing the configure file
You need to first run buildconf After this is complete you will then be able to use configure
automake amp libtool package was needed too
22 Configuring Web Server Proxies 21
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
apt-get install automake libtool
Enable the necessary modules
1 sudo a2enmod proxy
2 sudo a2enmod proxy_http
3 sudo a2enmod proxy_wstunnel
Add the config to Apache
The next step is adding the configuration to your virtualhostconf file typically located in etcapache2sites-availableThe below configuration assumes yoursquove used 4567 (default) port for NobeBB installation It also assumes you havethe bind address set to 127001
ProxyRequests off
ltProxy gtOrder denyallowAllow from all
ltProxygtProxyPass socketio1websocket ws1270014567socketio1websocketProxyPassReverse socketio1websocket ws1270014567socketio1websocket
ProxyPass socketio http1270014567socketioProxyPassReverse socketio http1270014567socketio
ProxyPass http1270014567ProxyPassReverse http1270014567
The last thing you need to be sure of is that the configjson in the NodeBB folder has use_port false Otherwise somefunctionality will not work properly
Example nodebbconfigjson
base_url httpwwwyoursitecomport 4567use_port falsesecret 55sb254c-62e3-4e23-9407-8655147562763bind_address 127001database redisredis
host 127001port 6379password database 0
bcrypt_rounds 12upload_path publicuploadsrelative_path
Change the domain and dont use the secret in the example above
22 Chapter 2 Cu higravenh NodeBB
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Configuring Varnish Cache
To be sure Varnish will work properly with NodeBB check that your configuration etcvarnishdefaultvclis optimized for websockets
backend nodebb host = 127001 your nodebb hostport = 4567 your nodebb port
sub vcl_recv
Pipe websocket connections directly to Nodejsif (reqhttpUpgrade ~ (i)websocket) set reqbackend = nodebbreturn (pipe)
NodeBBif (reqhttphost == forumyourwebsitecom) change this to match your hostif (requrl ~ ^socketio)
set reqbackend = nodebbreturn (pipe) return pass seems not working for websockets
return (pass) dont cache
sub vcl_pipe Need to copy the upgrade headerif (reqhttpupgrade) set bereqhttpupgrade = reqhttpupgrade
bull Nginx
bull Apache
bull Varnish Cache
22 Configuring Web Server Proxies 23
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
24 Chapter 2 Cu higravenh NodeBB
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 3
Chy NodeBB
Running NodeBB
The preferred way to start and stop NodeBB is by invoking its executable
bull nodebb start Starts the NodeBB server
bull nodebb stop Stops the NodeBB server
bull Alternatively you may use npm start and npm stop to do the same
The methods listed below are alternatives to starting NodeBB via the executable
Simple Nodejs Process
To start NodeBB run it with node (some distributions use the executable nodejs please adjust accordingly)
$ cd pathtonodebbinstall$ node app
However bear in mind that crashes will cause the NodeBB process to halt bringing down your forum Consider someof the more reliable options below
Supervisor Process
Using the supervisor package you can have NodeBB restart itself if it crashes
$ npm install -g supervisor$ supervisor app
As supervisor by default continues to pipe output to stdout it is best suited to development builds
25
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Forever Daemon
Another way to keep NodeBB up is to use the forever package via the command line interface which can monitorNodeBB and re-launch it if necessary
$ npm install -g forever$ forever start appjs
26 Chapter 3 Chy NodeBB
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 4
Cp nht NodeBB
Upgrading NodeBB
NodeBBrsquos periodic releases are located in the Releases These releases contain what is usually considered the mostbug-free code and is designed to be used on production-level instances of NodeBB
You can utilise git to install a specific version of NodeBB and upgrade periodically as new releases are made
To obtain the latest fixes and features you can also git clone the latest version directly from the repository(master branch) although its stability cannot be guaranteed Core developers will attempt to ensure that everycommit results in a working client even if individual features may not be 100 complete
As always the NodeBB team is not responsible for any misadventures loss of data data corruption or any otherbad things that may arise due to a botched upgrade - so please donrsquot forget to back up before beginning
Upgrade Path
NodeBBrsquos upgrade path is designed so that upgrading between versions is straightforward NodeBB will provideupgrade compatibility (via the --upgrade flag) between the latest version of a lower branch and the latest version ofthe higher branch For example if v022 is the latest version in the v02x branch you can switch to the v03xbranch and suffer no ill effects Upgrading from v020 to v03x is not supported and NodeBB will warn youwhen attempting to upgrade that you are not upgrading cleanly
Upgrading between patch revisions
eg v010 to v011
Patch revisions contain bugfixes and other minor changes Updating to the latest version of code for your specificversion branch is all that is usually required
Execute steps 1 through 3
27
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Upgrading between minor revisions
eg v013 to v020
Minor revisions contain new features or substantial changes that are still backwards compatible They may alsocontain dependent packages that require upgrading and other features may be deprecated (but would ideally still besupported)
Execute steps 1 through 4
Upgrade Steps
Note After upgrading between revisions (ie v004 to v005) it may be necessary to run the following upgrade stepsto ensure that any data schema changes are properly upgraded as well
1 Shut down your forum
While it is possible to upgrade NodeBB while it is running it is definitely not recommended particularly if it is anactive forum
$ cd pathtonodebb$ nodebb stop
2 Back up your data
Ghi chuacute This section is incomplete please take care to back up your files properly
Backing up Redis
As with all upgrades the first step is to back up your data Nobody likes database corruptionmisplacement
All of the textual data stored in NodeBB is found in a rdb file On typical installs of Redis the main database isfound at varlibredisdumprdb
Store this file somewhere safe
Backing up MongoDB
To run a backup of your complete MongoDB you can simply run
mongodump
which will create a directory structure that can be restored with the mongorestore command
It is recommended that you first shut down your database On Debian Ubuntu itrsquos likely to be sudo service mongodbstop
28 Chapter 4 Cp nht NodeBB
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Backing up LevelDB
As LevelDB is simply a collection of flat files just copy the database over to a safe location ex
cp -r pathtodb pathtobackups
Store this file somewhere safe
Avatars
Uploaded images (avatars) are stored in publicuploads Feel free to back up this folder too
cd pathtonodebbpublictar -czf ~nodebb_assetstargz uploads
3 Grab the latest and greatest code
Navigate to your NodeBB $ cd pathtonodebb
If you are upgrading from a lower branch to a higher branch switch branches as necessary Make sure you arecompletely up-to-date on your current branch
For example if upgrading from v032 to v043
$ git fetch Grab the latest code from the NodeBB Repository$ git checkout v04x Type this as-is Not v042 or v043 but v04x$ git merge originv04x
If not upgrading between branches just run the following command
$ git pull
This should retrieve the latest (and greatest) version of NodeBB from the repository
Alternatively download and extract the latest versioned copy of the code from the Releases Page Overwrite any filesas necessary This method is not supported
4 Run the NodeBB upgrade script
This script will install any missing dependencies upgrade any plugins or themes (if an upgrade is available) andmigrate the database if necessary
$ nodebb upgrade
Note nodebb upgrade is only available after v030 If you are running an earlier version run these instead
bull npm install
bull ls -d node_modulesnodebb | xargs -n1 basename | xargs npm update
bull node app --upgrade
6 Start up NodeBB amp Test
You should now be running the latest version of NodeBB
41 Upgrading NodeBB 29
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
30 Chapter 4 Cp nht NodeBB
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 5
Qun tr NodeBB
Administrative Functions
Ghi chuacute These docs are out of date If you are interested in updating these (preferably with screenshots) let us knowon the community forum because we are planning on a design overhaul of the ACP soon
To view the admin panel (if you are an admin) httpyour_nodebb_domaincomadmin
Top Menu (all can be easily reached by other means)
bull NodeBB ACP (Administrator Control Panel this view) httpyour_nodebb_domaincomadminindex(see Home below)
bull Forum httpyour_nodebb_domaincom (your main forum)
bull Home httpyour_nodebb_domaincomadminindex (see Home below)
bull Settings httpyour_nodebb_domaincomadminsettings (see Settings below)
Side Menu NodeBB
bull Home httpyour_nodebb_domaincomadminindex Links all go to nodebbcom homepage
ndash NOTE should all the links go to same place
ndash Message reminder of what version this is and to check for updates (See Upgrading NodeBB) NOTEwould a link to where the latest stable version is help
ndash Active Users lists number users per page-path () NOTE not clear exactly what the paths meanor how to visit that path
bull Categories httpyour_nodebb_domaincomadmincategories Filters Active Disabled Unit Tests List of Categories
ndash Icon Name Desc Action Disable
ndash Actions Save Add New
31
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
bull Users httpyour_nodebb_domaincomadminusers Filters Latest Users Top Posters Most Reputa-tion Action Search List of Users
ndash Icon Link Name Reputation(star) Number Posts(pencil) Action Ban
ndash Action Load More
bull Groups httpyour_nodebb_domaincomadmingroups
ndash List of Groups
ndash Name Desc Icon
ndash Action Delete Group NOTE What exactly can Groups be set up to do besides Admin
bull Topics httpyour_nodebb_domaincomadmintopics List of Topics
ndash Name [link to topic] Posted When and By Number posts (Topic+Replies) Thread ActionsPin(pushpin) Lock(lock) Delete(trashcan)
ndash Action Load More Topics
ndash Topic [from List of Topics link]
ndash Normal View of Topic+Reply Posts but with Link Edit Delete Actions all enabled for each Post Thread Tools
Pin Lock Move Delete
bull Themes (See Theming NodeBB) httpyour_nodebb_domaincomadminthemes List of (Custom |Bootswatch) Themes
ndash Actions Use Preview
ndash Action Revert (to base)
bull Plugins (See Writing Plugins for NodeBB) httpyour_nodebb_domaincomadminplugins List of Plu-gins
ndash Action Deactivate
ndash Info on making plugins
bull Settings httpyour_nodebb_domaincomadminsettings
ndash General Settings (textbox) Site Title (textbox) Site Description (textbox) Site Keywords (textbox) Imgur Client ID
NOTE How does this function
(textbox) Maximum User Image Size
ndash Privilege Thresholds (Use privilege thresholds to manage how much reputation a user must gain toreceive moderator access) (textbox) Manage Thread (textbox) Moderate Users (textbox) CreatePinned Topics
ndash Email Settings (textbox) Email Address (The following email address refers to the email that therecipient will see in the ldquoFromrdquo and ldquoReply Tordquo fields) (textbox) SMTP Server Host (Default127001) (textbox) SMTP Server Port
ndash User Settings (textbox) Minimum Username Length (textbox) Maximum Username Length (textbox) Minimum Password Length
ndash Post Settings (textbox) Post Delay (textbox) Minimum Title Length (textbox) Minimum PostLength (checkbox) Use Outgoing Links Warning Page
ndash Action Save
32 Chapter 5 Qun tr NodeBB
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
bull Redis httpyour_nodebb_domaincomadminredis Redis data storage stats
bull Logger httpyour_nodebb_domaincomadminlogger (checkbox) Enable HTTP logging (checkbox)Enable socketio event logging (textbox) Path to log file
bull MOTD (Message of the Day) httpyour_nodebb_domaincomadminmotd (textarea) You can entereither full HTML or Markdown text (checkbox) Show the Message of the Day
Side Menu Social Authentication (See Enabling Social Network Logins)
bull Twitter
bull httpyour_nodebb_domaincomadmintwitter
bull Facebook
bull httpyour_nodebb_domaincomadminfacebook
bull Google+
bull httpyour_nodebb_domaincomadmingplus
Side Menu Plugins (Shows installed plugins)
Side Menu Unit Tests (Will run qunit tests)
Social Network SSOs
NodeBB supports integration for Facebook Twitter and Google through third party plugins
bull npm install nodebb-plugin-sso-facebook
bull npm install nodebb-plugin-sso-twitter
bull npm install nodebb-plugin-sso-google
Other SSO vendors are available such as GitHub Please check the plugin directory for a list of all SSO vendors
After installing and activating them they require an API key in order to function
Register an application via the Facebook Developers page A credit card or mobile phone number may be required inorder to create a Developer account
Create a new application and obtain an Application Key and Application Secret
Ensure that ldquoWebsite with Facebook Loginrdquo is checked and that the URL to your NodeBB instance is specified in theldquoSite URLrdquo box Add that sitersquos domain to the ldquoApp Domainsrdquo field
Paste this key and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Twitter Developers page Create a new Application and obtain the Access Token andSecret
Important While setting up your application be sure to specify a Callback URL It does not have to correspond toyour installation it just cannot be blank
52 Social Network SSOs 33
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Paste this token and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin onyour NodeBB install)
Register an application at the Google API Console and obtain a Client ID and Secret
Paste this ID and secret into the appropriate boxes in the NodeBB Administration Panel (accessible via admin on yourNodeBB install)
Image Hosting APIs
Enabling Imgur Image Uploads
To enable post image attachments first create an imgur app from
httpsapiimgurcomoauth2addclient
You can use ldquoAnonymous usage without user authorizationrdquo
After that you will get a ldquoClient IDrdquo
Then install nodebb-plugin-imgur
npm install nodebb-plugin-imgur
Activate the plugin from the control panel and restart NodeBB
You should see a Imgur menu item in the control panel Paste the Client ID to the ldquoImgur Client IDrdquo in the pluginpage Save and you should be able to upload images by dragging them into the composer window
Uploading to Amazon S3
Ghi chuacute No documentation for this yet See the plugin thread for more information
34 Chapter 5 Qun tr NodeBB
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 6
ETHoacuteng goacutep cho NodeBB
NodeBB Style Guide
For the most part NodeBB follows the Google Javascript Style Guide
Code Formatting
Ghi chuacute The existing codebase as of July 2013 does not adhere to this style guide 100 If you see instances wherethe style guide is not adhered to feel free to restyle and send off a pull request
Indentation amp Bracing
NodeBB uses tabbed indentation Bracing should follow the One True Brace Style
if (condition) code here
else otherwise
Put conditionals and statements on separate lines and wrap with curly braces even if itrsquos just one line
if (leTired) haveANap()
35
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Errors
Most callbacks return an error as the first parameter Handle this error first before processing further
someFunction(parameters function(err data) if(err)
return callback(err) or handle error proceed as usual
)
Variables
Variables should always be prefaced with the var keyword
var foo = bar
Multiple declarations are to be included in the same var statement
var foo = barbar = baz
Semicolons
Use semicolons if at all possible
Nomenclature
CamelCase if at all possible
functionNamesLikeThis variableNamesLikeThis ClassNamesLikeThis EnumNamesLikeThisrarr˓methodNamesLikeThis CONSTANT_VALUES_LIKE_THIS foonamespaceNamesLikeThisbar andrarr˓filenameslikethisjs
Core Modules
Ghi chuacute This section is under construction Have a look at the modules folder for more information located at
publicsrcmodules
Alerts
The alert module is a toaster notification that can be called via the following syntax
36 Chapter 6 ETHoacuteng goacutep cho NodeBB
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
appalert(title Successmessage Heres an example of an alertlocation left-bottomtimeout 2500type successimage httpsiimgurcomdJBzcGTjpg
)
The above code will result in this notification (default styling)
To style this have a look at the vanilla themersquos modulesalertless and templatesalerttpl
Parameters
1 title - string which can be a language string as well Some core language strings that you can use hereinclude [[globalalertsuccess]] and [[globalalerterror]]
2 message - string which can be a language string as well
3 location (optional) - right-top (default) left-top right-bottom left-bottom
4 timeout (optional) - integer in milliseconds default is permanent until closed
5 type - error success info warningnotify
6 image (optional) - string URL to image
7 closefn (optional) - function This is called when the user closes the alert via the (X) button
8 clickfn (optional) - function This is called when the user clicks on the alert
62 Core Modules 37
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
38 Chapter 6 ETHoacuteng goacutep cho NodeBB
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 7
H thng plugin
Writing Plugins for NodeBB
So you want to write a plugin for NodeBB thatrsquos fantastic There are a couple of things you need to know beforestarting that will help you out
Like WordPress NodeBBrsquos plugins are built on top of a hook system in NodeBB This system exposes parts ofNodeBB to plugin creators in a controlled way and allows them to alter content while it passes through or executecertain behaviours when triggered
See the full list of hooks for more information
Filters and Actions
There are two types of hooks filters and actions
Filters act on content and can be useful if you want to alter certain pieces of content as it passes through NodeBBFor example a filter may be used to alter posts so that any occurrences of ldquoapplerdquo gets changed to ldquoorangerdquo Likewisefilters may be used to beautify content (ie code filters) or remove offensive words (profanity filters)
Actions are executed at certain points of NodeBB and are useful if yoursquod like to do something after a certain triggerFor example an action hook can be used to notify an admin if a certain user has posted Other uses include analyticsrecording or automatic welcome posts on new user registration
When you are writing your plugin make sure a hook exists where yoursquod like something to happen If a hook isnrsquotpresent file an issue and wersquoll include it in the next version of NodeBB
Configuration
Each plugin package contains a configuration file called pluginjson Here is a sample
39
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
id my-pluginname My Awesome Plugindescription Your plugins descriptionurl Absolute URL to your plugin or a Github repositorylibrary my-pluginjsstaticDirs
images publicimagesless [
assetsstyleless]hooks [
hook filterpostsave method filter hook actionpostsave method emailme
]languages pathtolanguages
The id property is a unique name that identifies the plugin
The library property is a relative path to the library in your package It is automatically loaded by NodeBB (if theplugin is activated)
The staticDirs property is an object hash that maps out paths (relative to your pluginrsquos root) to a directory thatNodeBB will expose to the public at the route pluginsYOUR-PLUGIN-ID
bull eg The staticDirs hash in the sample configuration maps pathtoyourpluginpublicimages to pluginsmy-pluginimages
The less property contains an array of paths (relative to your pluginrsquos directory) that will be precompiled into theCSS served by NodeBB
The hooks property is an array containing objects that tell NodeBB which hooks are used by your plugin and whatmethod in your library to invoke when that hook is called Each object contains the following properties (those with a are required)
bull hook the name of the NodeBB hook
bull method the method called in your plugin
bull priority the relative priority of the method when it is eventually called (default 10)
The languages property is optional which allows you to set up your own internationalization for your plugin (ortheme) Set up a similar directory structure as core for example languageen_GBmypluginjson
Writing the plugin library
The core of your plugin is your library file which gets automatically included by NodeBB if your plugin is activated
Each method you write into your library takes a certain number of arguments depending on how it is called
bull Filters send a single argument through to your method while asynchronous methods can also accept a callback
bull Actions send a number of arguments (the exact number depends how the hook is implemented) These argumentsare listed in the list of hooks
40 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Example library method
If we were to write method that listened for the actionpostsave hook wersquod add the following line to thehooks portion of our pluginjson file
hook actionpostsave method myMethod
Our library would be written like so
var MyPlugin = myMethod function(postData)
do something with postData here
Using NodeBB libraries to enhance your plugin
Occasionally you may need to use NodeBBrsquos libraries For example to verify that a user exists you would need tocall the exists method in the User class To allow your plugin to access these NodeBB classes use moduleparentrequire
var User = moduleparentrequire(user)Userexists(foobar function(err exists)
)
Installing the plugin
In almost all cases your plugin should be published in npm and your packagersquos name should be prefixed ldquonodebb-plugin-rdquo This will allow users to install plugins directly into their instances by running npm install
When installed via npm your plugin must be prefixed with ldquonodebb-plugin-rdquo or else it will not be found by NodeBB
As of v005 ldquoinstallingrdquo a plugin by placing it in the plugins folder is still supported but keep in mind that thepackage id and its folder name must match exactly or else NodeBB will not be able to load the plugin This featuremay be deprecated in later versions of NodeBB
Testing
Run NodeBB in development mode
nodebb dev
This will expose the plugin debug logs allowing you to see if your plugin is loaded and its hooks registered Activateyour plugin from the administration panel and test it out
Disabling Plugins
You can disable plugins from the ACP but if your forum is crashing due to a broken plugin you can reset all pluginsby executing
71 Writing Plugins for NodeBB 41
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
nodebb reset plugins
Alternatively you can disable one plugin by running
nodebb reset plugin=nodebb-plugin-im-broken
Available Hooks
The following is a list of all hooks present in NodeBB This list is intended to guide developers who are looking towrite plugins for NodeBB For more information please consult Writing Plugins for NodeBB
There are two types of hooks filters and actions Filters take an input (provided as a single argument) parse itin some way and return the changed value Actions take multiple inputs and execute actions based on the inputsreceived Actions do not return anything
Important This list is by no means exhaustive Hooks are added on an as-needed basis (or if we can see a potentialuse case ahead of time) and all requests to add new hooks to NodeBB should be sent to us via the issue tracker
Filters
filteradminheader_build
Allows plugins to create new navigation links in the ACP
filterpostsave
Argument(s) A postrsquos content (markdown text)
Executed whenever a post is created or edited but before it is saved into the database
filterpostget
Argument(s) A post object (javascript Object)
Executed whenever a post is retrieved but before being sent to the client
filterheaderbuild
Allows plugins to add new navigation links to NodeBB
filterregisterbuild
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull data the data passed to the template (javascript Object)
Allows plugins to add new elements to the registration form At the moment the only one supported islsquodatacaptchalsquo
42 Chapter 7 H thng plugin
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
filterpostparse
Argument(s) A post or signaturersquos raw text (String)
Executed when a post or signature needs to be parsed from raw text to HTML (for output to client) This is useful ifyoursquod like to use a parser to prettify posts such as Markdown or BBCode
filterpostscustom_profile_info
Allows plugins to add custom profile information in the topic viewrsquos author post block
filterregistercheck
Argument(s)
bull req the express request object (javascript Object)
bull res the express response object (javascript Object)
bull userData the user data parsed from the form
Allows plugins to run checks on information and deny registration if necessary
filterscriptsget
Allows to add client-side JS to the header and queue up for minification on production
filteruploadImage
filteruploadFile
filterwidgetsgetAreas
filterwidgetsgetWidgets
filtersearchquery
filterpostparse
filtermessagingsave
filtermessagingparse
filtersoundsget
filterpostgetPosts
filterpostgetFields
filterauthinit
filtercomposerhelp
72 Available Hooks 43
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
filtertopicthread_tools
filtertopicget
Passes in the final parsed topic data
filterusercreate
filteruserdelete
filteruserprofileLinks
filteruserverifycode
Parameters confirm_code
Ability to modify the generated verification code (ex for using a shorter verification code instead for SMS verification)
filterusercustom_fields
Parameters userData
Allows you to append custom fields to the newly created user ex mobileNumber
filterregistercomplete
Parameters uid destination
Set the post-registration destination or do post-register tasks here
filterwidgetrender
filtertemplatesget_virtual
Allows you to modify the apiget_templates_listing API call allowing ajaxification to custom templates that are notserved physically via the templates` parameter in ``pluginjson
filtertemplatesget_config
Allows you to add custom ajaxification rules in the apiget_templates_listing API call See httpsgithubcomNodeBBnodebb-theme-vanillablobmastertemplatesconfigjson for more details
Actions
actionappload
Argument(s) None
Executed when NodeBB is loaded used to kickstart scripts in plugins (ie cron jobs etc)
44 Chapter 7 H thng plugin
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
actionpageload
Argument(s) An object containing the following properties
bull template - The template loaded
bull url - Path to the page (relative to the sitersquos base url)
actionpluginactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is activated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was activated
actionplugindeactivate
Argument(s) A String containing the pluginrsquos id (eg nodebb-plugin-markdown)
Executed whenever a plugin is deactivated via the admin panel
Important Be sure to check the id that is sent in with this hook otherwise your plugin will fire its registered hookmethod even if your plugin was not the one that was deactivated
actionpostsave
Argument(s) A post object (javascript Object)
Executed whenever a post is created or edited after it is saved into the database
actionpostupvote
Argument(s) pid uid
Executed whenever a post is upvoted uid is the user that has triggered the upvote
actionpostdownvote
Argument(s) pid uid
Executed whenever a post is downvoted uid is the user that has triggered the downvote
actionemailsend
actionpostsetField
actiontopicedit
actiontopicpin
Called when toggling pinned state Object tid isPinned uid
72 Available Hooks 45
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
actiontopiclock
Called when toggling locked state Object tid isLocked uid
actiontopicmove
Called when moving a topic from one category to another Object tid fromCid toCid uid
actionpostedit
actionpostdelete
actionpostrestore
actionnotificationpushed
Argument(s) A notification object (javascript Object)
Executed whenever a notification is pushed to a user
actionconfigset
actiontopicsave
actiontopicdelete
actionusercreate
actionuserverify
Parameters uid a hash of confirmation data (ex confirm_link confirm_code) Useful for overriding the verificationsystem Currently if this hook is set the email verification system is disabled outright
actionuserfollow
Parameters fromUid toUid
lsquolsquoactionuserunfollow
Parameters fromUid toUid
actionuserset
Parameters field (str) value type (lsquosetrsquo lsquoincrementrsquo or lsquodecrementrsquo) Useful for things like awarding badges orachievements after a user has reached some value (ex 100 posts)
actionsettingsset
Parameters hash (str) object (obj) Useful if your plugins want to cache settings instead of pulling from DB everytimea method is called Listen to this and refresh accordingly
46 Chapter 7 H thng plugin
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Client Side Hooks
filtercategoriesnew_topic
actionpopstate
actionajaxifystart
actionajaxifyloadingTemplates
actionajaxifyloadingData
actionajaxifycontentLoaded
actionajaxifyend
actionreconnected
actionconnected
actiondisconnected
actioncategoriesloading
actioncategoriesloaded
actioncategoriesnew_topicloaded
actiontopicloading
actiontopicloaded
actioncomposerloaded
actioncomposertopicspost
actioncomposerpostsreply
actioncomposerpostsedit
actionwidgetsloaded
Settings Framework
If you want to make your plugin customizable you may use the Settings Framework NodeBB offers
Server-Side Access
First you need some default settings just create a new object for this
73 Settings Framework 47
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
var defaultSettings = booleans
someBool truemoreBools [false false true]
strings
someString hello worldmultiLineString somenlongntextarrayOfStrings [somenlongntexts and another one]
numbers
multiArrayDimensions [[4242][2121]]multiArrayDimensions2 [[4242][]]justSomeNumbers []oneNumber 3anotherNumber 2
someKeys [C+S+13] Ctrl+Shift+Enter
Now you can use the server-side settings-module to access the saved settings like this
var Settings = moduleparentrequire(settings)var mySettings = new Settings(myPlugin 01 defaultSettings function()
the settings are ready and can accessedconsolelog(mySettings === this) trueconsolelog(thisget(stringssomeString) === mySettingsget()strings
rarr˓someString) true)
The second parameter should change at least every time the structure of default settings changes Because of this itrsquosrecommended to use your plugins version
To use the settings client-side you need to create a WebSocket that delivers the result of mySettingsget()
The mySettings-object will cache the settings so be sure to use methods like mySettingssync(callback)when the settings got changed from somewhere else and mySettingspersist(callback) when you finishedmySettingsset(key value) calls
You need to create a socket-listener like following to allow the admin to initiate a synchronization with the settingsstored within database
var SocketAdmin = moduleparentrequire(socketioadmin)SocketAdminsettingssyncMyPlugin = function()
mySettingssync()
If you want to add a reset-functionality you need to create another socket-listener
SocketAdminsettingsgetMyPluginDefaults = function (socket data callback) callback(null mySettingscreateDefaultWrapper())
The methods of the mySettings object you probably want to use
bull constructor()
bull sync([callback]) Reloads the settings from database overrides local changes
bull persist([callback]) Saves the local changes within database
48 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
bull get([key]) Returns the setting(s) identified by given key If no key is provided the whole settings-objectgets returned If no such setting is saved the default value gets returned
bull set([key ]value) Sets the setting of given key to given value Remember that itrsquos just a local changeyou need to call persist in order to save the changes
bull reset([callback]) Persists the default settings
bull getWrapper() Returns the local object as it would get saved within database
bull createWrapper(version settings) Creates an object like it would get saved within database con-taining given information and settings
bull createDefaultWrapper() Creates an object like it would get saved within database containing the de-fault settings
Client-Side Access
The next step is making the settings available to the admin
You need to use the hooks filteradminheaderbuild (to display a link to your page within ACP) andactionappload (to create the needed route)
Within your page you can access the client-side Settings API via
require([settings] function (settings) var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper) [2]
)
To make a button with the id save actually save the settings you can add the following at [2]
$(save)click(function(event) eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)
As said before the server-side settings-object caches the settings so we emit a WebSocket to notify the server tosynchronize the settings after they got persisted
To use a reset-button you can add the following at [2]
$(reset)click(function(event) eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err data)
settingsset(myPlugin data wrapper function()socketemit(adminsettingssyncMyPlugin)
))
)
There you go the basic structure is done Now you need to add the form-fields
Each field needs an attribute data-key to reference its position within the settings The Framework does supportany fields whose jQuery-object provides the value via the val() method
73 Settings Framework 49
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
The plugin to use for a field gets determined by its data-type type or tag-name in this order
Additionally the following plugins are registered by default
bull array (types div array) An Array of any other fields Uses the object within data-attributes todefine the array-elements Uses data-new to define the value of new created elements
bull key (types key) A field to input keyboard-combinations
bull checkbox number select textarea Handle appropriate fields
A full list of all attributes that may influence the behavior of the default Framework
bull data-key the key to saveload the value within configuration-object
bull data-type highest priority type-definition to determine what kind of element it is or which plugin to associate
bull type normal priority type-definition
bull data-empty if false or 0 then values that are assumed as empty turn into null data-empty of arrays affecttheir child-elements
bull data-trim if not false or 0 then values will get trimmed as defined by the elements type
bull data-split if set and the element doesnrsquot belong to any plugin itrsquos value will get split and joined by its value intothe field
bull array-elements
ndash data-split separator (HTML allowed) between the elements defaults to
ndash data-new value to insert into new created elements
ndash data-attributes an object to set the attributes of the child HTML-elements tagName as special keywill set the tag-name of the child HTML-elements
bull key-fields
ndash data-trim if false or 0 then the value will get saved as string else as object providing followingproperties ctrl alt shift meta code char
ndash data-split separator between different modifiers and the key-code of the value that gets saved (onlytakes effect if trimming)
ndash data-short if not false or 0 then modifier-keys get saved as first uppercase character (only takeseffect if trimming)
bull select
ndash data-options an array of objects containing text and value attributes
The methods of the settings module
bull registerPlugin(plugin[ types]) Registers the given plugin and associates it to the given types ifany otherwise the plugins default types will get used
bull get() Returns the saved object
bull set(hash settings[ wrapper[ callback[ notify]]]) Refills the fields with given set-tings and persists them hash Identifies your plugins settings settings The object to save in database(settings-wrapper if you use server-side Settings Framework) wrapper (default lsquoformrsquo) The DOM-Element that contains all fields to fill callback (default null) Gets called when done notify (de-fault true) Whether to display saved- and fail-notifications
bull sync(hash[ wrapper[ callback]]) Resets the settings to saved ones and refills the fields
50 Chapter 7 H thng plugin
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
bull persist(hash[ wrapper[ callback[ notify]]]) Reads the settings from given wrapper(default lsquoformrsquo) and saves them within database
For Settings 20 support the methods load and save are still available but not recommended
Client-Side Example Template
An example template-file to use the same settings we already used server-side
lth1gtMy Pluginlth1gtlthr gt
ltform id=my_form_idgtltdiv class=rowgt
ltpgtlth2gtSettingslth2gtA boolean ltinput type=checkbox data-key=booleanssomeBoolgtltinputgt
rarr˓ltbrgtAn array of checkboxes that are selected by defaultltdiv data-key=booleansmoreBools data-attributes=data-typecheckbox
rarr˓ data-new=truegtltdivgtltbrgt
A simple input-field of any common type ltinput type=password data-key=rarr˓stringssomeStringgtltinputgtltbrgt
A simple textarea lttextarea data-key=stringsmultiLineStringgtltrarr˓textareagtltbrgt
Array of textareasltdiv data-key=stringsarrayOfStrings data-attributes=data-type
rarr˓textarea data-new=Hello Kitty ahem Worldgtltdivgtltbrgt
2D-Array of numbers that persist even when empty (but not empty rows)ltdiv data-key=numbersmultiArrayDimensions data-split=ltbrgt
data-attributes=data-typearraydata-attributestyperarr˓number data-new=[4221]gtltdivgtltbrgt
Same with persisting empty rows but not empty numbers if no row israrr˓given null will get saved
ltdiv data-key=numbersmultiArrayDimensions2 data-split=ltbrgt data-rarr˓empty=false
data-attributes=data-typearraydata-emptytruedata-rarr˓attributestypenumberdata-emptyfalse data-new=[4221]gtltdivgtltbrgt
Array of numbers (new 42 step 21)ltdiv data-key=numbersjustSomeNumbers data-attributes=data-type
rarr˓numberstep21 data-new=42gtltdivgtltbrgtSelect with dynamic optionsltselect data-key=numbersoneNumber data-options=[value2text2
rarr˓value3text3]gtltselectgtltbrgtSelect that loads fasterltselect data-key=numbersanotherNumbergtltbrgt
ltoption value=2gt2ltoptiongtltoption value=3gt3ltoptiongt
ltselectgt
Array of Key-shortcuts (new Ctrl+Shift+7)ltdiv data-key=someKeys data-attributes=data-typekey data-new=
rarr˓Ctrl+Shift+55gtltdivgtltbrgtltpgt
ltdivgtltbutton class=btn btn-lg btn-warning id=resetgtResetltbuttongt
73 Settings Framework 51
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
ltbutton class=btn btn-lg btn-primary id=savegtSaveltbuttongtltformgt
ltscriptgtrequire([settings] function (settings)
var wrapper = $(my_form_id) [1]settingssync(myPlugin wrapper)$(save)click(function(event)
eventpreventDefault()settingspersist(myPlugin wrapper function()
socketemit(adminsettingssyncMyPlugin))
)$(reset)click(function(event)
eventpreventDefault()socketemit(adminsettingsgetMyPluginDefaults null function (err
rarr˓data) settingsset(myPlugin data wrapper function()
socketemit(adminsettingssyncMyPlugin))
))
)ltscriptgt
Custom Settings-Elements
If you want do define your own element-structure you can create a plugin for the Settings Framework
This allows you to use a whole object like a single field which - besides comfort in using multiple similar objects -allows you to use them within arrays
A plugin is basically an object that contains at least an attribute types that contains an array of strings that associateDOM-elements with your plugin
You can add a plugin at [1] using the method settingsregisterPlugin
To customize the way the associated fields get interpreted you may add the following methods to your plugin-object
All given elements are instances of JQuery
All methods get called within Settings-scope
bull use() Gets called when the plugin gets registered
bull [HTML-Element|JQuery] create(type tagName data) Gets called when a new elementshould get created (eg by expansion of an array)
bull destruct(element) Gets called when the given element got removed from DOM (eg by array-splice)
bull init(element) Gets called when an element should get initialized (eg after creation)
bull [value] get(element trim empty) Gets called whenever the value of the given element is re-quested trim Whether the result should get trimmed empty Whether considered as empty valuesshould get saved too
bull set(element value trim) Gets called whenever the value of the given element should be set togiven one trim Whether the value is assumed as trimmed
52 Chapter 7 H thng plugin
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
For further impression take a look at the default plugins
You should also take a look at the helper-functions within Settings in order to create your own plugins There are afew methods that take response to call the methods of other plugins when fittingly
73 Settings Framework 53
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
54 Chapter 7 H thng plugin
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 8
H thng widgets
Writing Widgets for NodeBB
See the original blog post for a high level overview and screenshots of the widget system
Embedding HTML and JavaScript
You donrsquot need to be a developer to figure this out Head over to the Themes control panel and click on the Widgetstab Create a new HTML widget by dragging and dropping the widget onto whatever template you want
Copy and paste HTML or JavaScript into the widget and hit save - yoursquore done
You can optionally give your widget a container by dragging and dropping from the containers section onto yourselected widget
If yoursquore looking for some sample scripts head over to our plugins section and look for any topic labellednodebb-script-xyz Donrsquot forget to submit your scripts and ideas as well
Creating Widgets
You can define widgets in both plugins and themes If yoursquore building a plugin which simply delivers a widget(or collection of widgets) we strongly suggest you follow the nodebb-widget-xyz nomenclature instead whenpublishing
Registering your widget
Listen to this hook to register your widget
hook filterwidgetsgetWidgets method defineWidgets callbacked true
55
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Pass this back in the array
Content defines the form that is displayed to customize your widget in the admin panel
Listening to your widget
NodeBB core will call your widget on the appropriate page load by way of the hooks system Thehook will be named after your widgetrsquos namespace (see previous example) - like so filterwidgetrenderwidget_namespace
This will pass in an object with the following useful properties
bull objarea - will have location template url
bull objdata - will have your admin-defined data in the example from the previous section you will be exposedan objdatamyKey
Defining Widget Areas in Themes
A Widget Area is characterized by a template and a location Themes can share widgets if they define the same WidgetAreas If an admin switches themes widgets that were previously defined in a Widget Area incompatible with the newtheme are saved
Listen to this hook to register your Widget Area
hook filterwidgetsgetAreas method defineWidgetAreas callbacked true
Pass this back in the array
name Category Sidebartemplate categorytpllocation sidebar
And thatrsquos all You can define as many Widget Areas in your theme as you wish If yoursquore still stuck have a look atthis commit which upgraded the Cerulean theme to use the widget system
56 Chapter 8 H thng widgets
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 9
Nn tng giao din
Creating a new NodeBB Theme
NodeBB is built on Twitter Bootstrap which makes theming incredibly simple
Packaging for NodeBB
NodeBB expects any installed themes to be installed via npm Each individual theme is an npm package and userscan install themes through the command line ex
npm install nodebb-theme-modern-ui
The themersquos folder must contain at least two files for it to be a valid theme
1 themejson
2 themeless
themeless is where your themersquos styles will reside NodeBB expects LESS to be present in this file and willprecompile it down to CSS on-demand For more information regarding LESS take a look at the project homepage
Note A suggested organization for themeless is to import multiple smaller files instead of placing all of thestyles in the main themeless file
Configuration
The theme configuration file is a simple JSON string containing all appropriate meta data regarding the theme Pleasetake note of the following properties
bull id A unique id for a theme (eg ldquomy-themerdquo)
bull name A user-friendly name for the theme (eg ldquoMy Themerdquo)
57
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
bull description A onetwo line description about the theme (eg ldquoThis is the theme I made for my personalNodeBBrdquo)
bull screenshot A filename (in the same folder) that is a preview image (ideally 370x250 or an aspect ratio of1481)
bull url A fully qualified URL linking back to the themersquos homepageproject
bull templates (Optional) A system path (relative to your pluginrsquos root directory) to the folder containing tem-plate files If not specified NodeBB will search for the ldquotemplatesrdquo directory and then simply fall back to usingvanillarsquos template files
Child Themes
If your theme is based off of another theme simply modify your LESS files to point to the other theme as a base
topicless
As topicless from the theme nodebb-theme-vanilla was imported those styles are automatically incor-porated into your theme
Important If you depend on another theme make sure that your theme specifically states this in its packagejsonFor example for the above theme as we depend on nodebb-theme-vanilla we would explicitly state this byadding a new section into the packagejson file
peerDependencies nodebb-theme-vanilla ~001
Rendering Engine
How it works
Every page has an associated API call Template file and Language File
For example if you navigate to topic351nodebb-wiki the application will load three resources The API re-turn apitopic351nodebb-wiki and the template in this example ldquotopictplrdquo and the appropriate language fileldquotopicjsonrdquo
Just prepend api to the URLrsquos path name to discover the JSON return Any value in that return can be utilized in yourtemplate
A pagersquos name corresponds to the template and languagersquos filename (ex httpdomaincomtopicxyzcorrelates to topictpl) Sometimes this is not the case - ex userxyz loads accounttpl Have a look atthe custom_mapping section in publictemplatesconfigjson for more details
Templating Basics
Using the API return as your guide you can utilize any of those values in your templatelogic Using the above APIcall as an example for anything in the root level of the return you can do something like
topic_name
58 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
To access values in objects
privilegesread
And finally you can loop through arrays and create blocks like so
lt-- BEGIN posts --gtpostscontentlt-- END posts --gt
The above will create X copies of the above block for each item in the posts array
Templating Logic
NodeBBrsquos templating system implements some basic logic Using the same API call as above for our example Youcan write IF conditionals like so
lt-- IF unreplied --gtThis thread is unrepliedlt-- ENDIF unreplied --gt
Another example
lt-- IF disableSocialButtons --gtltbuttongtShare on Facebookltbuttongtlt-- ELSE --gtSharing has been disabledlt-- ENDIF disableSocialButtons --gt
We can check for the length of an array like so
lt-- IF postslength --gtThere be some postslt-- ENDIF postslength --gt
While looping through an array we can check if our current index is the first or last like so
lt-- BEGIN posts --gtlt-- IF first --gtlth1gtMain Author postsusernamelth1gt
lt-- ENDIF first --gtpostscontentlt-- IF last --gtEnd of posts Click here to scroll to the top
lt-- ENDIF last --gtlt-- END posts --gt
For more advanced documentation have a look at the templatesjs repository
Exposing template variables to client-side JavaScript
There are two ways of letting our JS know about data from the server-side apart from WebSockets (TODO will becovered in a different article)
92 Rendering Engine 59
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Via jQueryget
If we require data from a different page we can make a $get call to any other API call For example if we wantedto know more about a specific user we could make a call like so
$get(RELATIVE_PATH + apiuserpsychobunny function(user) consolelog(user)
)
See this API call in action httpcommunitynodebborgapiuserpsychobunny
Via Template Variables
In topictpl for example we can add a hidden input like so
ltinput type=hidden template-variable=pageCount value=pageCount gt
The template system will immediately parse all of these and expose them via the following method
ajaxifyvariablesget(pageCount)
This is the ideal method of letting JS know about important variables within the template
Internationalization
The template engine interfaces with the internationalization system as well We can embed variables into languagestrings Letrsquos use this API call as well as this language file as an example We can now do something like the following
[[registerhelpusername_restrictions minimumUsernameLengthrarr˓maximumUsernameLength]]
Which will translate this string
A unique username between 1 and 2 characters
to
A unique username between 2 and 16 characters
Advanced Topics
Dynamically requiring and rendering a template file from client-side JavaScript
The template engine lazy loads templates on an as-needed basis and caches them If your code requires a template orpartial on-demand then you can
ajaxifyloadTemplate(myTemplate function(myTemplate) var html = templatesparse(myTemplate myData)
)
You can also access the invidual blocks inside each template which is handy for doing things like (for example)rendering a new postrsquos ltligt and dynamically sticking it in an already loaded ltulgt
60 Chapter 9 Nn tng giao din
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Some stuff herelt-- BEGIN posts --gtWe just want to pull this block onlylt-- END posts --gt some stuff here
ajaxifyloadTemplate(myTemplate function(myTemplate) var block = templatesgetBlock(myTemplate posts)var html = templatesparse(block myData)
)
Rendering templates on server-side Nodejs
The templating system hooks into Express just like most other templating frameworks Just use either apprenderor resrender to parse the appropriate template
resrender(myTemplate myData)
apprender(myTemplate myData function(err parsedTemplate) consolelog(parsedTemplate)
)
92 Rendering Engine 61
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
62 Chapter 9 Nn tng giao din
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 10
Tagravei nguyecircn cho nhagrave phaacutet trin
Developerrsquos Resources
Ghi chuacute Khu vc nagravey dang dc xacircy dng
Lotildei
bull Xacircy dng trang qun tr mi (ETHatilde li thi)
Plugins
bull Phaacutet trin plugins vi Grunt vagrave Coffeescript
bull Vit NodeBB plugin du tiecircn ca bn
Giao din
Widgets
63
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
64 Chapter 10 Tagravei nguyecircn cho nhagrave phaacutet trin
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 11
Tr giuacutep cho d aacuten NodeBB
Helping out the NodeBB Project
NodeBB is an open source project and will forever remain free Herersquos a number of ways you can help us even if youarenrsquot a programmer
bull Like and share our content on Facebook
bull Follow us on Twitter and perhaps tweet NodeBB is most awesome forum software NodeBB
bull Update our wiki ) We need everything from developmentdesign tutorials to user friendly how-to guides
bull Tell everybody about NodeBB including your grandma and her cats
bull Submit a pull request or two or three
bull Build a new theme
bull Write a plugin
bull Keep the link back to us on the footer of your own NodeBB )
bull Blog about us Give the gift of SEO juice this Christmas
bull Help Translate NodeBB - Itrsquos a really simple translation tool and you donrsquot need to know how to code
bull Join our community and give us a hard time about bugs and missing features
Translating NodeBB to another language
NodeBB uses Transifex which is a user friendly visual tool which allows any individual to translate text into a languageof their choice You donrsquot need to be a programmer to do this so what are you waiting for Join the translation teamnow )
65
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Writing Documentation
These docs were written using Sphinx and published using rtfdorg
You can edit these docs directly on GitHub or by clicking on ldquoView page sourcerdquo on the top right of any page
If you wish you can clone the repository and compile the documentation yourself Check out the Getting Startedsection for more info on how to accomplish the latter
Documentation are auto-compiled and pushed to rtfdorg after every commit
66 Chapter 11 Tr giuacutep cho d aacuten NodeBB
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 12
Khc phc Tr giuacutep
Need Help
Frequently Asked Questions
If you experience difficulties setting up a NodeBB instance perhaps one of the following may help
How do I startstoprestart NodeBB
You can call the nodebb executable to start and stop NodeBB
$ nodebbWelcome to NodeBBUsage nodebb start|stop|reload|restart|log|setup|reset|upgrade|dev|watch
start Start the NodeBB serverstop Stops the NodeBB serverreload Restarts NodeBBrestart Restarts NodeBBlog Opens the logging interface (useful for debugging)setup Runs the NodeBB setup scriptreset Disables all plugins restores the default themeupgrade Run NodeBB upgrade scripts ensure packages are up-to-datedev Start NodeBB in interactive development modewatch Start NodeBB in development mode and watch for changes
How do I upgrade my NodeBB
Please consult Upgrading NodeBB
67
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
I upgraded NodeBB and now X isnrsquot working properly
Please consult Upgrading NodeBB
I installed an incompatible plugin and now my forum wonrsquot start
If you know which plugin caused problems disable it by running nodebb resetplugin=nodebb-plugin-pluginName
Otherwise disable all plugins by running nodebb reset plugins
Is it possible to install NodeBB via FTP
It is possible to transfer the files to your remote server using FTP but you do require shell access to the server in orderto actually ldquostartrdquo NodeBB Here is a handy guide for installing NodeBB on DigitalOcean
Irsquom getting an ldquonpm ERRrdquo error
For the most part errors involving npm are due to Nodejs being outdated If you see an error similar to this one whilerunning npm install
npm ERR Unsupportednpm ERR Not compatible with your version of nodenpm connect2711
Yoursquoll need to update your Nodejs version to 08 or higher
To do this on Ubuntu
add-apt-repository ppachris-leanodejs apt-get update ampamp apt-get dist-upgrade -y
If successful running the following command should show a version higher than 08
apt-cache policy nodejs
URLs on my NodeBB (or emails) still have the port number in them
If you are using nginx or Apache as a reverse proxy you donrsquot need the port to be shown Simply run nodebb setupand specify the base URL without a port number
Alternatively edit the configjson file using your favourite text editor and change use_port to false
The ldquoRecently Logged In IPsrdquo section only shows 127001
NodeBBs running behind a proxy may have difficulties determining the original IP address that requests come fromIt is important that the proxy server provides the referral IP header
In nginx ensure that the following line is present in your server block
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
In addition ensure that the use_port option is set to false in your NodeBBrsquos configjson
68 Chapter 12 Khc phc Tr giuacutep
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
Submit Bugs on our Issue Tracker
Before reporting bugs please ensure that the issue has not already been filed on our tracker or has already beenresolved on our support forum If it has not been filed feel free to create an account on GitHub and create a new issue
Ask the NodeBB Community
Having trouble installing NodeBB Or did something break Donrsquot hesitate to join our forum and ask for helpHopefully one day yoursquoll be able to help others too )
121 Need Help 69
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
NodeBB Documentation Release 041
70 Chapter 12 Khc phc Tr giuacutep
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71
CHAPTER 13
Ch muc vagrave bng
bull genindex
bull modindex
bull search
71