DbEntry 开发实践:Wiki 系统(四)

上回书说到,VisualWiki系统已经有了显示、编辑、历史页面,不过,程序里也有了一小段重复的代码,所以我们这一次先进行一点儿重构工作。

  首先,在VisualWiki.Models里建立一个Helpers目录,然后在其中创建一个CommonHelper类,并且把我们设置HyperLink的代码整理成一个SetLink函数:

ExpandedBlockStart.gif 代码
namespace  VisualWiki.Models.Helpers
{
    
public   static   class  CommonHelper
    {
        
public   static   void  SetLink(HyperLink link,  string  pageName,  string  linkPageName,  string  title)
        {
            
if  (pageName.ToLower()  ==  linkPageName.ToLower())
            {
                link.Enabled 
=   false ;
            }
            
else
            {
                link.Enabled 
=   true ;
                link.NavigateUrl 
=   new  UrlBuilder(linkPageName).Add( " title " , title).ToString();
            }
        }
    }
}

  然后打开web.config,找到pages段,在namespaces里增加这个新的namespace:

< add  namespace ="VisualWiki.Models.Helpers" />

  Main.master的Page_Load函数也可以修改为:

ExpandedBlockStart.gif 代码
protected   void  Page_Load( object  sender, EventArgs e)
{
    var pageName 
=  Request.Url.Segments[ 2 ];
    CommonHelper.SetLink(Edit, pageName, 
" Edit.aspx " , title);
    CommonHelper.SetLink(History, pageName, 
" History.aspx " , title);
}

  运行程序,验证HyperLink工作的和以前一样,title这个字符串用的到处都是,也不太好,再在Helpers里加一个Const类,用来定义一些常量,把程序里的替换掉吧:

ExpandedBlockStart.gif 代码
namespace  VisualWiki.Models.Helpers
{
    
public   static   class  Const
    {
        
public   static   readonly   string  TitleName  =   " title " ;
        
public   static   readonly   string  HomeName  =   " Home " ;
    }
}

  好的,现在来考虑另一个问题:怎么新增Wiki页?有一个新增按钮,然后填写标题和内容么?我不喜欢这样,另外,怎么在一个Wiki页里链接到另一个Wiki页呢?恩,不需要我们考虑的太多,SharePoint中的Wiki的处理方法就很好,一个Wiki页中,双中括号内的文字,就是另一篇Wiki的标题,它会被显示为一个链接,点击链接,到达另一个Wiki页,这时如果还没有建立新的Wiki页,点击Edit链接就可以了,和Home页一样。所以,我们需要一个函数,提取双中括号内的内容,并且替换成一个超链接,查找替换操作很容易出现差1的问题,对于内部有html标签的情况,也要把标签去除,另外,对于只有左双中括号,或者只有右双中括号的情况,也需要能处理,所以,先写几个单元测试吧:

ExpandedBlockStart.gif 代码
namespace  VisualWiki.UnitTests
{
    [TestFixture]
    
public   class  TestHelper
    {
        [Test]
        
public   void  TestTestGenerateShowTest1()
        {
            
const   string  text  =   " abc [[bb]] xyz " ;
            var act 
=  CommonHelper.GenerateShowText(text);
            Assert.AreEqual(
" abc <a href=\ " Show.aspx ? title = bb\ " >bb</a> xyz " , act);
        }

        [Test]
        
public   void  TestTestGenerateShowTest2()
        {
            
const   string  text  =   " abc [[bb xyz " ;
            var act 
=  CommonHelper.GenerateShowText(text);
            Assert.AreEqual(
" abc [[bb xyz " , act);
        }

        [Test]
        
public   void  TestTestGenerateShowTest3()
        {
            
const   string  text  =   " abc bb]] xyz " ;
            var act 
=  CommonHelper.GenerateShowText(text);
            Assert.AreEqual(
" abc bb]] xyz " , act);
        }

        [Test]
        
public   void  TestTestGenerateShowTest4()
        {
            
const   string  text  =   " [[bb]] " ;
            var act 
=  CommonHelper.GenerateShowText(text);
            Assert.AreEqual(
" <a href=\ " Show.aspx ? title = bb\ " >bb</a> " , act);
        }

        [Test]
        
public   void  TestTestGenerateShowTest5()
        {
            
const   string  text  =   " [[x<b>y</b>z]] " ;
            var act 
=  CommonHelper.GenerateShowText(text);
            Assert.AreEqual(
" <a href=\ " Show.aspx ? title = xyz\ " >x<b>y</b>z</a> " , act);
        }

        [Test]
        
public   void  TestTestGenerateShowTest6()
        {
            
const   string  text  =   " [[bb]] aa [[cc]] " ;
            var act 
=  CommonHelper.GenerateShowText(text);
            Assert.AreEqual(
" <a href=\ " Show.aspx ? title = bb\ " >bb</a> aa <a href=\ " Show.aspx ? title = cc\ " >cc</a> " , act);
        }
    }
}

  写这个函数,算不上很困难,但也不是很简单,经过几次小折腾,应该就可以让所有的单元测试通过了:

ExpandedBlockStart.gif 代码
public   static   string  GenerateShowText( string  text)
{
    var ret 
=   new  StringBuilder();
    
int  last  =   0 ;
    
while  ( true )
    {
        
int  m  =  text.IndexOf( " [[ " , last);
        
if  (m  >=  last)
        {
            
int  n  =  text.IndexOf( " ]] " , m);
            
if  (n  >  m)
            {
                ret.Append(text.Substring(last, m 
-  last));
                var title 
=  text.Substring(m  +   2 , n  -  m  -   2 );
                var url 
=   new  UrlBuilder( " Show.aspx " );
                url.Add(Const.TitleName, RemoveHtmlTag(title));
                var link 
=  HtmlBuilder.New.a(url.ToString()).include(title).end;
                ret.Append(link);
                last 
=  n  +   2 ;
                
continue ;
            }
        }
        ret.Append(text.Substring(last));
        
break ;
    }
    
return  ret.ToString();
}

public   static   string  RemoveHtmlTag( string  text)
{
    var ret 
=   new  StringBuilder();
    
int  last  =   0 ;
    
while  ( true )
    {
        
int  m  =  text.IndexOf( " < " , last);
        
if  (m  >=  last)
        {
            
int  n  =  text.IndexOf( " > " , m);
            
if  (n  >  m)
            {
                ret.Append(text.Substring(last, m 
-  last));
                last 
=  n  +   1 ;
                
continue ;
            }
        }
        ret.Append(text.Substring(last));
        
break ;
    }
    
return  ret.ToString();
}


  恩,代码能工作,只不过,两个函数里有不少相似的代码,再重构一下吧:

ExpandedBlockStart.gif 代码
public   static   string  GenerateShowText( string  text)
{
    
return  ProcessSymbol(text,  " [[ " " ]] " ,
        title 
=>
        {
            var url 
=   new  UrlBuilder( " Show.aspx " );
            url.Add(Const.TitleName, RemoveHtmlTag(title));
            var link 
=  HtmlBuilder.New.a(url.ToString()).include(title).end;
            
return  link.ToString();
        });
}

public   static   string  RemoveHtmlTag( string  text)
{
    
return  ProcessSymbol(text,  " < " " > " null );
}

public   static   string  ProcessSymbol( string  text,  string  left,  string  right,
    CallbackHandler
< string string >  callback)
{
    var ret 
=   new  StringBuilder();
    
int  last  =   0 ;
    
while  ( true )
    {
        
int  m  =  text.IndexOf(left, last);
        
if  (m  >=  last)
        {
            
int  n  =  text.IndexOf(right, m);
            
if  (n  >  m)
            {
                ret.Append(text.Substring(last, m 
-  last));
                
if (callback  !=   null )
                {
                    var inner 
=  text.Substring(m  +  left.Length, n  -  m  -  left.Length);
                    ret.Append(callback(inner));
                }
                last 
=  n  +  right.Length;
                
continue ;
            }
        }
        ret.Append(text.Substring(last));
        
break ;
    }
    
return  ret.ToString();
}

  运行单元测试,全部通过,既然有了可以工作的GenerateShowText函数,就把它加入Show.aspx里吧,需要修改的地方并不多,一个是原来的article.Content,一个是h.Content。修改之后,运行程序,进入Home页,编辑它,加入有双中括号的内容,比如Hello,保存,回到Show.aspx,显示Hello为链接,点击此链接,进入Hello页,在这里可以进行Hello页编辑、浏览历史等操作了。就是回不去Home页,恩,在Main.master里加个Home的链接吧:

< href ="Show.aspx?title=Home" > Home </ a >  |

  现在,我们的Wiki系统已经基本成型,显示、编辑、新建、历史都有了,我们还想给它加入路径功能,不过,先把代码提交了吧。目前的代码: VisualWiki4.7z

  未完待续……

转载于:https://www.cnblogs.com/lephone/archive/2009/12/03/create_wiki_by_using_dbentry_4.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值