本文介绍了如何让nicEditor快速成长? (几个问题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的例子定义了一个将nicEditor绑定到textarea的snaplet。以下问题不仅与以下示例有关,还可能与其他一些类似案例有关。

The example below defines a snaplet to bind nicEditor to textarea. The following questions are not only related to the example below, but probably they are related to some other similar cases..


  1. 新手可以关注下面的说明(如何澄清)?

  2. 如何让示例使用更少的步骤或更简单? (是否有可能与下面的内容大致相同?)

  3. 这使用了解释拼接。如果可能的话,一个snaplet也应该提供编译拼接吗?
  4. 一个snaplet可能会给一个默认处理程序或几个处理程序以典型的情况。处理程序可以在下面的SnapNic.hs中定义。给用户一些回调机制,然后?

-

{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE OverloadedStrings #-}

 ------------------------------------------------------------------------------
-- | This module defines nicEditor snaplet, just a short example to show,
-- how snaplets can be defined together with splices.
-- License: BSD3.
-- Here are hopefully easy instructions, how to use or try:
--
-- 1. Make a directory, we'll use "netry" below, go there.
--  Initialize a project, e.g. "snap init default".
-- 2. Copy this file to netry/src-directory as SnapNic.hs.
-- 3. Add "import SnapNic" to Site.hs and to Application.hs
-- 4. Add ", _niced :: Snaplet Nicsnap" to data App in Application.hs
--
-- 5. Add "n <- nestSnaplet "niced" niced nicsnapInit" to
--    app :: SnapletInit App App in Site.hs.
-- 6. Add "addNicEditSplices n" to the same function as in step 5.
-- 7. Change the return-line of the same function as in step 5:
--      "return $ App h s a n"
--    that is, add "n" into the end. We need this because of step 4.
--
-- 8. Make route, e.g. ", ("/netext",   with auth handleNEtext)" to
--    routes-function in Site.hs
--
-- 9. And then add handler into Site.hs:
--    handleNEtext :: Handler App v ()
--    handleNEtext = method GET handleForm <|> method POST handleFormSubmit
--      where
--       handleForm = render "textedit"
--       handleFormSubmit = do
--        p <- getParam "ots"
--        writeText "Submitting text from textarea...\n"
--        writeText (T.pack (show p))
--
-- 10. Last, add the following 2 templates to "netry/snaplets/heist/templates".
--    (This could be made simpler, but this works as an example of apply-tag.)
--    textedit.tpl:
--      <apply template="base">
--         <apply template="_textedit" />
--      </apply>
--    _textedit.tpl:
--       <h2>Your nic editor</h2>
--         <form method="post" action="netext">
--           <neTA/>
--           <button name="ne" value="ne" type="Submit">Send text</button>
--         </form>
--         <neScript/>
--
-- 11. Compile everything "cabal install -fdevelopment". After that,
--     if everything compiled, "netry -p 8000", start your browser and go
--     to "localhost:8000/netext".
--
-- TODO! This could use the config-files at least for some parameters, and more
-- tags,please. Tags could use some attributes (for example, size parameters
-- could be given as attributes of tags)...
--
module SnapNic
  ( Nicsnap (..)
  , nicsnapInit
  , addNicEditSplices
  ) where

------------------------------------------------------------------------------
import           Control.Lens   (makeLenses, view, (^.))
import qualified Data.Text as T (Text, append, pack)
import           Data.Maybe     (fromJust, fromMaybe)
import           Snap.Core      (MonadSnap)
import           Snap.Snaplet   (Snaplet
                                , makeSnaplet
                                , snapletValue
                                , SnapletInit
                                , Initializer
                                )
import           Snap.Snaplet.Heist     (HasHeist, addSplices)
import qualified Text.XmlHtml as X      (Node (Element, TextNode))
import qualified Heist.Interpreted as I (Splice)

------------------------------------------------------------------------------
-- | Nicsnap has fields that can be used to set some basic properties.
-- The editor can have a title and its size can be set. Javascript can be
-- local or remote.
data Nicsnap = Nicsnap
  { _nicsnap  :: T.Text       -- title
  , _areaSize :: (Int,Int)    -- rows, cols
  , _areaRef  :: T.Text       -- how to apply nicEditors?
  -- (This may not be sufficient in order to refer in some other way, TODO!)
  , _localR   :: Maybe T.Text -- local route to nicEdit.js
  , _webR     :: T.Text       -- route to nicEdit's javascript source.
  }

makeLenses ''Nicsnap          -- makes webR and other lenses


------------------------------------------------------------------------------
-- | Configurations are given here. This could use config-files...
-- What other things to configure?
-- If you want to make a local copy of the nicEdit, then add a static route
-- to the "routes"-function.
nicsnapInit :: SnapletInit b Nicsnap
nicsnapInit = makeSnaplet "nicsnap" "NicEditor snaplet " Nothing $ do
   let m  = "Nic editor title"
       aS = (20,80)::(Int,Int) -- rows, cols
       aR = "nicEditors.allTextAreas" -- TODO! We need to be able to tell,
       -- which textareas have editors in a page.
       lR = Nothing
       -- lR = Just "/nicEdit.js"
       -- If localR is nothing, then webR is used with the following addr.
       wR = "http://js.nicedit.com/nicEdit-latest.js"
   return $ Nicsnap m aS aR lR wR

------------------------------------------------------------------------------

-- | Internal, this makes the script-tag.
-- Input could be e.g. txt = "/nicEdit.js"
srcElem :: T.Text -> X.Node
srcElem txt = X.Element "script"
   [("src",txt),("type","text/javascript")] []

-- | Internal, this makes the script-tag. At the moment this changes all
-- textareas to niceditors, if the example input below is used. TODO!...
-- Input could be e.g.  txt = "nicEditors.allTextAreas"
srcOnLoad :: T.Text -> X.Node
srcOnLoad txt = X.Element "script" [("type","text/javascript")]
   [X.TextNode (T.append (T.append "bkLib.onDomLoaded(" txt) ");")]


-- | Internal, used to define "divs", where we give a label and size to
-- textarea. Also ids and names.
-- TODO! ids and names could be parameters.
divLabelTX :: T.Text -> T.Text -> T.Text -> X.Node
divLabelTX title r c =  X.Element "div" [("class", "required")]
   [ X.Element "label" [("for","ots")]
        [X.TextNode title]
   , X.Element "textarea"
        [("id","ots"), ("name","ots"), ("cols",c), ("rows",r)]
        [X.TextNode " "]
   ]

-- | Internal, this can be used in splice-definition.
-- TODO! ids and names could be parameters, too.
nicTextAreaAdd :: MonadSnap m => T.Text -> (Int,Int) -> I.Splice m
nicTextAreaAdd title (r,c) = return [divLabelTX
  title
  (T.pack . show $ r)
  (T.pack . show $ c)]

-- | Add script-tags to web page with splice that tell, what javascript
-- library to use...
nicEditAdd :: MonadSnap m => T.Text -> T.Text -> I.Splice m
nicEditAdd src edElems = return (srcElem src : [srcOnLoad edElems])

------------------------------------------------------------------------------

-- | Get the route to the javascript library that is applied (either local
-- library or construct a link to a web address).
nicRoute :: Nicsnap -> T.Text
nicRoute ns = let mlR = ns ^. localR in fromMaybe (ns ^. webR) mlR

------------------------------------------------------------------------------

-- | neTextAreaTag and neScripTag are used in addSplices to define the tags
-- to be used in templates.
-- What other tags could be useful? Maybe a way to add a nicEditor directly
-- with one or more button bind to it ("send", "clear", etc). TODO!
neTextAreaTag = "neTA"     :: T.Text
neScriptTag   = "neScript" :: T.Text

-- | Make the tags to be used in templates. At the moment, only the above
-- tags are defined.
addNicEditSplices :: HasHeist b => Snaplet Nicsnap -> Initializer b v ()
addNicEditSplices n = let m = view snapletValue n in addSplices
  [(neTextAreaTag, nicTextAreaAdd (m ^. nicsnap) (m ^. areaSize))
  ,(neScriptTag,   nicEditAdd (nicRoute m) (m ^. areaRef) )
  ]
------------------------------------------------------------------------------


推荐答案

我不是新手,所以我无法回答你的第一个问题,但我对其他一些问题有了一些想法和答案。首先,如果你真的希望这是一个严重的问题(无论是出于教学目的还是实际使用),你应该把它变成一个小型项目。这将消除您的指示中的第2步。接下来,snaplets可以定义他们自己的路线。你可以通过调用功能。这将消除步骤8. Snaplets还可以提供自己的文件系统资源,这些资源将被复制到使用它的任何项目中。您可以使用此功能来消除步骤10,并提供默认配置文件。有关如何执行此操作的更多信息,请查看部分。

I'm not a newbie, so I can't answer your first question, but I've got some thoughts and answers to some of the others. First of all, if you really want this to be a serious snaplet (either for instructional purposes or real use) you should probably make this into a cabal project. That would eliminate step 2 from your instructions. Next, snaplets can define their own routes. You can do that in your initializer by calling the addRoutes function. This would eliminate step 8. Snaplets can also provide their own filesystem resources that will be copied into any project that uses it. You could use this feature to eliminate step 10, as well as provide default config files. For more information on how to do this, look at the filesystem data and automatic installation section at the end of the snaplet tutorial.

目前,可能是关于如何使用snaplets必须提供的大多数功能的最佳示例。如果你想使它成为其他人使用的真正强大的通用目标,那么你肯定应该包括解释和编译的拼接。我最近添加了一些捕捉包使得它更容易编写自动工作在编译或解释拼接模式的通用snaplets。这段代码还没有在hackage上,但我很快就会发布它。

Currently, snaplet-postgresql-simple is probably the best example on hackage of how to use most of the features that snaplets have to offer. If you want to make this a really robust general purpose snaplet for other people to use, then you should definitely include both interpreted and compiled splices. I recently added some new functions to the snap package that make it easier to write generic snaplets that automatically work in either compiled or interpreted splice mode. That code isn't on hackage yet, but I'll probably be releasing it soon.

我也一直在研究,它可以更全面地使用snaplet API的大部分功能。与snaplet-postgresql-simple不同,这个snaplet定义了模板和拼接。它仍在开发中,但已经展示了大部分功能。其余的工作将主要是抛光和健壮。

I have also been working on another snaplet that makes much more comprehensive use of most of the features of the snaplet API. Unlike snaplet-postgresql-simple, this snaplet defines templates and splices. It is still under development, but already demonstrates most of the features. The remaining work will be mostly just polish and robustness.

这篇关于如何让nicEditor快速成长? (几个问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 06:04