萌梦论坛版式更新计划



  • 由于萌梦论坛版式的更新,需要花费很多的精力去调试来得到效果,这必然不是一个非常容易的事儿,因此我们将这里写下一个帖子,督促这个计划的进展情况。目前的情况是我们已经选定好了我们的发展方向,是参考http://pickvox.com 拾音网的页面布局来设计我们论坛的页面布局。这里还需要做的是,我们如何想办法来在数据安全的情况下改变前台显示的内容,并且得到很好的更新。此外,如何在原有数据库设计的基础上,设计出更加适合我们业务需要的数据模型出来,这样能够支持我们制作更多的插件以及产品的后台逻辑。



  • @jiangcaiyang 为了详细了解NodeBB数据库的运行机制,我下载了Robomongo来进行数据库的查看。



  • 加油↖(^ω^)↗



  • @Accelerated
    src/user/data.js中我们可以找到这样的函数:

    	User.setUserField = function(uid, field, value, callback) {
    		callback = callback || function() {};
    		db.setObjectField('user:' + uid, field, value, function(err) {
    			if (err) {
    				return callback(err);
    			}
    			plugins.fireHook('action:user.set', {uid: uid, field: field, value: value, type: 'set'});
    			callback();
    		});
    	};
    
    	User.setUserFields = function(uid, data, callback) {
    		callback = callback || function() {};
    		db.setObject('user:' + uid, data, function(err) {
    			if (err) {
    				return callback(err);
    			}
    			for (var field in data) {
    				if (data.hasOwnProperty(field)) {
    					plugins.fireHook('action:user.set', {uid: uid, field: field, value: data[field], type: 'set'});
    				}
    			}
    			callback();
    		});
    	};
    
    	User.incrementUserFieldBy = function(uid, field, value, callback) {
    		callback = callback || function() {};
    		db.incrObjectFieldBy('user:' + uid, field, value, function(err, value) {
    			if (err) {
    				return callback(err);
    			}
    			plugins.fireHook('action:user.set', {uid: uid, field: field, value: value, type: 'increment'});
    
    			callback(null, value);
    		});
    	};
    
    	User.decrementUserFieldBy = function(uid, field, value, callback) {
    		callback = callback || function() {};
    		db.incrObjectFieldBy('user:' + uid, field, -value, function(err, value) {
    			if (err) {
    				return callback(err);
    			}
    			plugins.fireHook('action:user.set', {uid: uid, field: field, value: value, type: 'decrement'});
    
    			callback(null, value);
    		});
    	};
    

    这里可以让我们了解如何解决Javascript中User对象和数据库打交道的。



  • 我发现,这个函数User.setUserField很重要,如果我们制作了一个插件,可以通过这个方法来向数据库写入数据。



  • 我们将要采用nodebb-plugin-ns-embed这个插件来对我们的一些需要嵌入的表单以及视频等的内容嵌入进来。



  • 如果有好的文章,可以通过nodebb-plugin-ns-likes这个插件来决定是否喜欢。



  • 这个插件nodebb-plugin-session-sharing的作用是与你的NodeBB共享会话。非常适合既通过电脑网页端登录,也通过手机端登录的方式。



  • 彩阳兄一定要加油↖(^ω^)↗



  • 继续努力!现在研究这个插件nodebb-plugin-poll



  • 这个插件nodebb-plugin-poll的内容非常丰富,既有动态内容,也有静态网页的内容,更有依赖第三方插件的内容。是非常值得参考的好插件。我们需要详细研究一下,看如何模仿出一个符合我们业务的插件出来。
    之所以学习nodebb-plugin-poll这个插件,是因为我们的业务需要和数据库打交道,而这个插件能够将本来不支持投票的功能添加进来。其中包含了对数据库的存入和读取。我们在其中的lib/poll.js中包含了对NodeBB中数据库的操作。



  • 我们意识到制作这个插件有相当的难度,需要我们再想个办法,先实现简单的再说。这里呢,我们会仔细规划论坛新的内容,把板块规划好,争取能够给大家一个崭新的面貌。



  • 今天研究NodeBB的主题插件:nodebb-theme-lavender发现,这个主题在theme.less上是依赖nodebb-theme-vanilla的。所以这个主题插件并不是独立存在的。



  • 又转向研究了论坛标题文字显示效果。

    general -> navigation

    如果设置icon为no-icon,并且设置Text Class为空,那么在标题栏会只会显示文字,而不会显示图标了。
    0_1471876215172_upload-9d9e3680-84c7-4fda-b29d-40ee64ed54e2



  • 有关新的主页设计方案,我打算参考NodeBB这个比较好的插件,nodebb-plugin-custom-homepg,我们先学习这个插件的使用方法,然后模仿制作一个类似的插件,但是使用的是我们自己喜欢的布局格式,这样能够达到我们满意的显示效果。💯 💚



  • @jiangcaiyang 学习bootstrap的知识:

    .col-xs-搜索超小屏幕 手机 (<768px);
    .col-sm-小屏幕 平板 (≥768px);
    .col-md-中等屏幕 桌面显示器 (≥992px)(栅格参数);
    .col-lg-大屏幕 (≥1200px)桌面。
    例如 <div class="col-xs-6 col-md-3"> 这个div在屏幕中占的位置是:1在超小屏幕中占6列 也就是屏幕的一半(6/12) 2.在中单屏幕中占3列也就是1/4(3/12)。 如果我们要在小屏幕上并排显示3个div(12/3=4),在大屏幕上显示6个 则col-xs-4 col-md-2
    这样我们就可以控制我们自己想要的什么排版了。
    还有一种情况是 <div class="col-sm-10 col-md-8"> 后面跟的div中col-sm的参数如果为3 也就是
    <div class="col-sm-10 col-md-8"></div>
    <div class="col-sm-3 col-md-4"></div>
    如果是这样 这两个div在小屏幕中会排2排 因为10+3>12 ,在中等屏幕中可以排同一排 8+4=12



  • 考察这个NodeBB的前端html模板:

    <div class="row">
    	<div class="col-md-9 col-xs-12" no-widget-class="col-lg-12 col-xs-12" no-widget-target="hp-sidebar">
    		<div widget-area="hp-content">
    			<!-- BEGIN widgets -->
    			{widgets.html}
    			<!-- END widgets -->
    		</div>
    	</div>
    	<div class="col-md-3 col-xs-12">
    		<div widget-area="hp-sidebar">
    			<!-- BEGIN widgets -->
    			{widgets.html}
    			<!-- END widgets -->
    		</div>
    	</div>
    </div>
    

    其中的no-widget-classno-widget-target是什么意思呢?后面我在acp.min.js文件中找到了相关代码,看来是这么处理的:

    	ajaxify.widgets.reposition = function(location) {
    		$('body [no-widget-class]').each(function() {
    			var $this = $(this);
    			if ($this.attr('no-widget-target') === location) {
    				$this.removeClass();
    				$this.addClass($this.attr('no-widget-class'));
    			}
    		});
    	};
    


  • 记录一下:如果把modernizr.js加入nodebb论坛中,会出现无法显示论坛内容的错误;
    如果把外部的jquery加入nodebb论坛中,会出现
    0_1472017996954_upload-7ef46e67-09f3-4968-8758-38e95bdec208
    这样的错误。



  • @jiangcaiyang 我终于知道了!
    那就是,NodeBB这边儿的插件nodebb-plugin-widget-essentials其中的templates有两套widgets。一套是admin,表示在管理员状态下进行渲染的页面,还有一套则是widgets,表示在网站前台下进行渲染的页面。通过library.js中勾住filter:widget.render:*来提供的函数来自定义渲染方法进行渲染。原来如此。



  • @jiangcaiyang 接下来,我们可能需要这么操作:模仿nodebb-plugin-widget-essentials里面有关控件的渲染方法,进行前台和后台分别进行渲染。这里后台提供一些控件,让用户设置图片。然后前台真正渲染图片。


Log in to reply
 

最近的回复

  • 看了你的脚本,看来PowerShell是一种shell的方言,支持function和自定义的符号。和bash还不一样。
    我以前也写过Apple Script,看来大家都在shell语言上加上自己的特性啊。
    顺便了解到你们主要用Visual Studio开发Qt应用的。😁 😁

    read more
  • @wentaojia2014
    代码中的 {1} 是自动生成的,注意删掉

    read more
  • 脚本玩家路过一下😁
    我写了一段Powershell脚本,可以一键打开/关闭调试信息和代码优化。
    原理就是解析.sln文件(xml格式),找到关联的所有.vcproj文件(也是xml格式),并把其中的字段修改掉。

    看脚本

    # filename: DebugInfoSwitch.ps1 Add-Type -AssemblyName System.Xml.Linq # 获取绝对路径 function GetAbsolutePath { [OutputType([string])] param([string]$filePath) $aPath = Resolve-Path $filePath return Split-Path $aPath } # 解析sln文件,提取出project列表 function ParseSolution { [OutputType([string[]])] param([string]$solutionFile) $parttern = [regex]"^Project*" [string[]] $projs = @() Get-Content $solutionFile | Where-Object {$_ -match $parttern} | ForEach-Object { $items = $_.ToString().Split(',') if ($items[1].EndsWith("vcxproj`"")) { $projs += $items[1] } } return $projs } #Write-Host($debugGroup | Format-Table | Out-String ) function UpdateDebugInfo { param([System.Xml.Linq.XNamespace]$xNamespace,[System.Xml.Linq.XElement] $group, [bool]$isOpen) [System.Xml.Linq.XElement]$xClCompile = $group.Element($xNamespace + "ClCompile") [System.Xml.Linq.XElement]$xLink = $group.Element($xNamespace + "Link") [System.Xml.Linq.XElement]$format = $xClCompile.Element($xNamespace + "DebugInformationFormat") [System.Xml.Linq.XElement]$optimization = $xClCompile.Element($xNamespace + "Optimization") [System.Xml.Linq.XElement]$generate = $xLink.Element($xNamespace + "GenerateDebugInformation") if ($null -eq $format) { $format = [System.Xml.Linq.XElement]::new($xNamespace + "DebugInformationFormat") $xClCompile.Add($format) } if ($null -eq $optimization) { $optimization = [System.Xml.Linq.XElement]::new($xNamespace + "Optimization") $xClCompile.Add($optimization) } if ($null -eq $generate) { $generate = [System.Xml.Linq.XElement]::new($xNamespace + "GenerateDebugInformation") $xLink.Add($generate) } if ($isOpen) { $format.SetValue("ProgramDatabase"); $optimization.SetValue("Disabled"); $generate.SetValue("true"); } else { $format.SetValue("None"); $optimization.SetValue("MaxSpeed"); $generate.SetValue("false"); } } function SwitchDebugInfo { param([string]$projPath, [bool]$open, [bool]$isRelease) if (Test-Path($projPath)) { [System.Xml.Linq.XDocument]$xDoc = [System.Xml.Linq.XDocument]::Load($projPath) [System.Xml.Linq.XNamespace]$xNamespace = $xDoc.Root.GetDefaultNamespace(); [System.Xml.Linq.XElement]$group = $null $groups = $xDoc.Root.Elements($xNamespace + "ItemDefinitionGroup") foreach ($i in $groups) { if ($isRelease) { if ($i.Attribute("Condition").Value -match "^*Release*") { $group = $i; break; } } else { if ($i.Attribute("Condition").Value -match "^*Debug*") { $group = $i; break; } } } UpdateDebugInfo $xNamespace $group $open $xDoc.Save($projPath) } } #脚本入口函数 function Main { param([string]$sln, [bool]$open, [bool]$isRelease) Write-Host("sln file ", $sln) $slnPath= GetAbsolutePath $sln $projList = ParseSolution $sln $t = $projList.Split(' ') | ForEach-Object { $s = $_.ToString() if ($s) { $projPath=-Join($slnPath, '\', ($s.SubString(1, $s.Length - 2) )) SwitchDebugInfo $projPath $open $isRelease } } } function Usage { Write-Host ("Usage: DebugInfoSwitch.ps1 slnFilePath mode[D/d for Debug, R/r for Release] open[Y/y for open, N/n for close]") Write-Host ("Example for open Release mode debugInfo: DebugInfoSwitch.ps1 xxx.sln R y") Write-Host ("Example for close Debug mode debugInfo: DebugInfoSwitch.ps1 xxx.sln d N") } #检查参数 [string]$sln = "" [bool]$open = $true [bool]$isRelease = $false if ( $args.Count -ne 3) { Usage return } $sln = $args[0] if ($args[1] -eq "D" -or $args[1] -eq "d") { $isRelease = $false } elseif ($args[1] -eq "R" -or $args[1] -eq "r") { $isRelease = $true } else { Usage return } if ($args[2] -eq "Y" -or $args[2] -eq "y") { $open = $true } elseif ($args[2] -eq "N" -or $args[2] -eq "n") { $open = $false } else { Usage return } #调用主函数 Main $sln $open $isRelease

    用的时候,再写个bat脚本,调用这个ps1并传参数就行了。
    比如打开Release模式的调试信息、同时关掉优化开关

    @echo off powershell.exe -NoProfile -ExecutionPolicy Bypass -File DebugInfoSwitch.ps1 ./you/path/to.sln R N

    关闭调试信息、打开优化开关,则是传相反的参数

    @echo off powershell.exe -NoProfile -ExecutionPolicy Bypass -File DebugInfoSwitch.ps1 ./you/path/to.sln R Y

    read more
  • 我将USD在Linux中依赖的文件和脚本放在了我创建的QQ群里,我们的QQ群是“上海USD研究小组”。加入本小组,可以快速地在USD中上手解决编译问题,以及快速得到同行的响应。
    上海USD研究小组

    read more

关注我们

微博
QQ群