Yesod Mform and hamlet - yesod

Hi I am new to yesod and following the documentation to make a form. In the documentation the form template was created in .hs file itself. But I have a separate hamlet where I want to customize.
I want to access "fields" in my hamlet file. The expected type of 'generateFormPost' is (xml, Enctype) . Can anybody tell me what I should be returning from 'tableMform extra' . I think it should be in xml format. But I think I should not be using toWidget as in below example of documentation.
tableMform extra = do
fields <- forM lis (\(w,h) -> mopt intField "this is not used" (Just h) )
return (fields) ---I know this line has the type error. Can anybody suggest how to deal with it
{-
--I am referring this code from yesod website to make my form. In this it was using runFormGet, but I want use generateFormPost and moreover it was creating a widget which is used in displaying the website. I don't want to create the widget here but in my hamlet file where the 'fields' is accessed via interpolation.
personForm :: Html -> MForm Handler (FormResult Person, Widget)
personForm extra = do
(nameRes, nameView) <- mreq textField "this is not used" Nothing
(ageRes, ageView) <- mreq intField "neither is this" Nothing
let personRes = Person <$> nameRes <*> ageRes
let widget = do
toWidget
[lucius|
##{fvId ageView} {
width: 3em;
}
|]
[whamlet|
#{extra}
<p>
Hello, my name is #
^{fvInput nameView}
\ and I am #
^{fvInput ageView}
\ years old. #
<input type=submit value="Introduce myself">
|]
return (personRes, widget)
-}
getHomeR :: Handler Html
getHomeR = defaultLayout $ do
-- Generate the form to be displayed
(fields, enctype) <- generateFormPost tableMform
let (fires,fiview) = unzip fields
$(widgetFile "layout")
|]
Please let me know if there is any misunderstanding. I have idea of how to get the form from the way done in the documentation, but I want to use a separate hamlet file, as I want to customize the look of the form.
Thanks
Sai
EDIT:
Sorry, I wasn't clear. I was trying to make a Mform where instead of creating the layout of the form in the ".hs" file , I wanted to give the layout in hamlet file. I have done it through http://pastebin.com/fwpZsKXy . But after doing that I could split it in to two files as I wanted. I have solved those errors. Thanks anyways

I got it. I was not clear of what "tableMform extra" has to return. I know that it has to return something of type [(FormResult a, xml)][1] . But then I was not sure what the type of "forM lis ((w,h) -> mopt intField (fromString w) (Just h) )" -- Line 2 was , So I followed what was done in documentation did it in the way it was done there.(without use of external widget file) .
After doing that I tried to do in the way I wanted to do i.e using a separate hamlet, julius and lucius files. http://pastebin.com/FgGph2CU . It worked !!
In summary I wasn't clear of the 'type' of "forM lis ((w,h) -> mopt intField (fromString w) (Just h) )" . Once I figured that out, it was easy.

Related

How to make Date Editable while using Glass mapper

Today i am facing one issue which has following requirement.
Date should be Editable.
Date should be in particular format.
My Code is like below which is not working.
foreach(var item in Model)
{
<div>#Editable(item, x => x.Start_Date.ToString("MMMM dd,yyyy"))</div>
}
I have tried following approach but throwing "DateParameters" namespace error.
#Editable(item, x=> x.Start_Date, new DateParameters { Format = "MMMM dd,yyyy"})
Also i have learner following thing but how can i achieve this ?
To make a field editable takes two parameters, this has been used to make the Date field editable. The first parameter instructs Glass.Mapper which field to make editable, the second parameter then specifies what the output should be when the page is not in page editing mode. This allows you to control the output of the field when in the two different modes.
Can anybody help me ?
For Experience editor mode, this works for me in razor view:
#Editable(model => model.SomeDateField, new { Format = "dd-MM-yyyy" })
Sitecore 8.2 though, with Glass 4.4.
What you want to do is to provide the default format but keep things the same for the main glass stuff. Like so:
foreach(var item in Model)
{
<div>#Editable(item, x => x.Start_Date, x=>x.Start_Date.ToString("MMMM dd,yyyy"))</div>
}
This will make the date a normal date when editing, but allow you to format it for the final page.
Usually in this case i use different code for "Normal View" and "Experience Editor", so for normal view you need only to display the date with format without making it editable, and on experience editor you need only to edit the date field the author will not care about the date format with experience editor, so your code will be like this :
foreach(var item in Model)
{
{
#if (Sitecore.Context.PageMode.IsExperienceEditorEditing)
{
<div>#Editable(item, x => x.Start_Date)</div>
}
else
{
<div>#item.Start_Date.ToString("MMMM dd,yyyy")</div>
}
}
}
I have tried that as well but it is throwing an error like below
**Value cannot be null. Parameter name: objectToSwitchTo
at Sitecore.Diagnostics.Assert.ArgumentNotNull(Object argument, String argumentName)
at Sitecore.Common.Switcher2.Enter(TValue objectToSwitchTo)
at Glass.Mapper.Sc.GlassHtml.MakeEditable[T](Expression1 field, Expression1 standardOutput, T model, Object parameters, Context context, Database database, TextWriter writer)**
Any help on this ?

How to import Shakespearean Templates in Yesod?

I was using QuasiQuotations in Yesod, and everything worked fine. BUT my file became very large and not nice to look at. Also, my TextEditor does not highlight this syntax correctly. That is why is split my files like so:
getHomeR :: Handler Html
getHomeR = do
webSockets chatApp
defaultLayout $ do
$(luciusFile "templates/chat.lucius")
$(juliusFile "templates/chat.julius")
$(hamletFile "templates/chat.hamlet")
If this is wrong, please do tell. Doing runghc myFile.hs throws many errors like this:
chat_new.hs:115:9:
Couldn't match expected type ‘t0 -> Css’
with actual type ‘WidgetT App IO a0’
The lambda expression ‘\ _render_ajFK
-> (shakespeare-2.0.7:Text.Css.CssNoWhitespace . (foldr ($) ...))
...’
has one argument,
but its type ‘WidgetT App IO a0’ has none
In a stmt of a 'do' block:
\ _render_ajFK
...
And this.
chat_new.hs:116:9:
Couldn't match type ‘(url0 -> [(Text, Text)] -> Text)
-> Javascript’
with ‘WidgetT App IO a1’
Expected type: WidgetT App IO a1
Actual type: JavascriptUrl url0
Probable cause: ‘asJavascriptUrl’ is applied to too few arguments
...
And also one for the HTML (Hamlet).
Thus, one per template.
It seems that hamletFile and others treat templates as self-contained, while yours are referencing something from each other. You can play with order of *File calls, or use widgetFile* from Yesod.Default.Util module:
$(widgetFileNoReload def "chat")
The Reload variant is useful for development - it would make yesod devel to watch for file changes and reload them.

Could not deduce (blaze-markup-0.6.3.0:Text.Blaze.ToMarkup Day) arising from a use of ‘toHtml’

I'm trying to use Yesod to build a simple web site and I'm starting with the code from Max Tagher's excellent intro on Youtube, YesodScreencast. I've forked his code from GitHub, and I would like to add a date to the posting to indicate when it was published, but I'm running into the problem that I can't quite figure out given my low experience with Haskell and beginner's experience with Yesod. I've been unable to find an answer via the Googleplex.
Yesod provides a native dayField in Yesod.Form.Fields, so I thought that all I needed to do was to add the postdate Field in BlogPost the following to config/models using Day:
BlogPost
title Text
postdate Day
article Markdown
and add it to the blogPostForm in PostNew.hs:
blogPostForm :: AForm Handler BlogPost
blogPostForm = BlogPost
<$> areq textField (bfs ("Title" :: Text)) Nothing
<*> areq dayField (bfs ("Postdate" :: Day)) Nothing
<*> areq markdownField (bfs ("Article" :: Text)) Nothing
When this compiles I get the following error message:
Handler/Home.hs:16:11:
Could not deduce (blaze-markup-0.6.3.0:Text.Blaze.ToMarkup Day)
arising from a use of ‘toHtml’
from the context (PersistEntity BlogPost)
bound by a pattern with constructor
Entity :: forall record.
PersistEntity record =>
Key record -> record -> Entity record,
in a lambda abstraction
at Handler/Home.hs:16:11-34
In the first argument of ‘asWidgetT GHC.Base.. toWidget’, namely
‘toHtml (blogPostPostdate post_apZp)’
In a stmt of a 'do' block:
(asWidgetT GHC.Base.. toWidget)
(toHtml (blogPostPostdate post_apZp))
In the expression:
do { (asWidgetT GHC.Base.. toWidget)
((blaze-markup-0.6.3.0:Text.Blaze.Internal.preEscapedText
GHC.Base.. Data.Text.pack)
"<h4><li><a href=\"");
(getUrlRenderParams
>>=
(\ urender_apZq
-> (asWidgetT GHC.Base.. toWidget)
(toHtml
(\ u_apZr -> urender_apZq u_apZr [] (PostDetailsR id_apZo)))));
(asWidgetT GHC.Base.. toWidget)
((blaze-markup-0.6.3.0:Text.Blaze.Internal.preEscapedText
GHC.Base.. Data.Text.pack)
"\">");
(asWidgetT GHC.Base.. toWidget)
(toHtml (blogPostPostdate post_apZp));
.... }
If I change Day to Text, everything works as I expect. I'm not sure why Yesod can't deal with a Day since it has a dayField in Yesod.Form.Fields that I would expect to handle this. I figure this is something simple, but I can't seem to determine what I need to do to fix this error.
It appears there is no instance for ToMarkup for the Date datatype.
You could supply an instance yourself:
instance ToMarkup Date where
toMarkup = toMarkup . show
Which turns your date into a string and then converts it to Markup. If the default show instance doesn't fit your needs you could supply a formatter yourself and put it in the place of show.

c++, cscope, ctags, and vim: Finding classes that inherit from this one

In a rather large code base with a few layers is there a way in vim or from the command line to find all classes that are derived from a base class? grep is an option but can be slow since grep does not index.
Neither cscope nor ctags allow us to deal with inheritance directly but it's relatively easy to work around that limitation because derived classes are also indexed.
cscope
In cscope, looking for "C symbol" Foobar usually lists the original class and classes inheriting from it. Since the search is done against a database, it is lightning fast.
Alternatively, you could use cscope's egrep searching capabilities with a pattern like :.*Foobar to list only classes inheriting from Foobar.
So, even if we don't have a dedicated "Find classes inheriting from this class" command, we can get the work done without much effort.
ctags
While ctags allows you to include inheritance information with --fields=+i, that information can't be used directly in Vim. The inherits field is parsed by Vim, though, so it might be possible to build a quick and dirty solution using taglist().
ack, ag
Those two programs work more or less like grep but they are targeted toward searching in source code so they are really faster than grep.
In my Vim config, :grep is set to run the ag program instead of the default grep so, searching for classes derived from the class under the cursor would look like:
:grep :.*<C-r><C-w><CR>
Here are the relevant lines from my ~/.vimrc:
if executable("ag")
set grepprg=ag\ --nogroup\ --nocolor\ --ignore-case\ --column
set grepformat=%f:%l:%c:%m,%f:%l:%m
endif
If you build your tags files with Exuberant CTags using inheritance information (see the --fields option), then the following script will work. It adds an :Inherits command which takes either the name of a class (e.g. :Inherits Foo) or a regular expression.
Like the :tag command, you indicate that you want the search with a regex by preceding it with a '\' character, e.g. :Inherits \Foo.*.
The results are put into the window's location list, which you browse with :ll, :lne, :lp, etc. VIM doesn't seem to allow scripts to modify the tag list which is what I'd prefer.
If you're wondering why I don't use taglist() for this, it's because taglist() is incredibly slow on large tag files. The original post had a version using taglist(), if you're curious you can browse the edit history.
" Parse an Exuberant Ctags record using the same format as taglist()
"
" Throws CtagsParseErr if there is a general problem parsing the record
function! ParseCtagsRec(record, tag_dir)
let tag = {}
" Parse the standard fields
let sep_pos = stridx(a:record, "\t")
if sep_pos < 1
throw 'CtagsParseErr'
endif
let tag['name'] = a:record[:sep_pos - 1]
let tail = a:record[sep_pos + 1:]
let sep_pos = stridx(tail, "\t")
if sep_pos < 1
throw 'CtagsParseErr'
endif
" '/' will work as a path separator on most OS's, but there
" should really be an OS independent way to build paths.
let tag['filename'] = a:tag_dir.'/'.tail[:sep_pos - 1]
let tail = tail[sep_pos + 1:]
let sep_pos = stridx(tail, ";\"\t")
if sep_pos < 1
throw 'CtagsParseErr'
endif
let tag['cmd'] = tail[:sep_pos - 1]
" Parse the Exuberant Ctags extension fields
let extensions = tail[sep_pos + 3:]
for extension in split(extensions, '\t')
let sep_pos = stridx(extension, ':')
if sep_pos < 1
if has_key(tag, 'kind')
throw 'CtagsParseErr'
endif
let tag['kind'] = extension
else
let tag[extension[:sep_pos - 1]] = extension[sep_pos + 1:]
endif
endfor
return tag
endfunction
" Find all classes derived from a given class, or a regex (preceded by a '/')
" The results are placed in the current windows location list.
function! Inherits(cls_or_regex)
if a:cls_or_regex[0] == '/'
let regex = a:cls_or_regex[1:]
else
let regex = '\<'.a:cls_or_regex.'\>$'
endif
let loc_list = []
let tfiles = tagfiles()
let tag_count = 0
let found_count = 0
for file in tfiles
let tag_dir = fnamemodify(file, ':p:h')
try
for line in readfile(file)
let tag_count += 1
if tag_count % 10000 == 0
echo tag_count 'tags scanned,' found_count 'matching classes found. Still searching...'
redraw
endif
if line[0] == '!'
continue
endif
let tag = ParseCtagsRec(line, tag_dir)
if has_key(tag, 'inherits')
let baselist = split(tag['inherits'], ',\s*')
for base in baselist
if match(base, regex) != -1
let location = {}
let location['filename'] = tag['filename']
let cmd = tag['cmd']
if cmd[0] == '/' || cmd[0] == '?'
let location['pattern'] = cmd[1:-2]
else
let location['lnum'] = str2nr(cmd)
endif
call add(loc_list, location)
let found_count += 1
endif
endfor
endif
endfor
catch /^OptionErr$/
echo 'Parsing error: Failed to parse an option.'
return
catch /^CtagsParseErr$/
echo 'Parsing error: Tags files does not appear to be an Exuberant Ctags file.'
return
catch
echo 'Could not read tag file:' file
return
endtry
endfor
call setloclist(0, loc_list)
echo tag_count 'tags scanned,' found_count 'matching classes found.'
endfunction
command! -nargs=1 -complete=tag Inherits call Inherits('<args>')
In lh-cpp, I define the command :Children. It relies on a ctags database, and as a consequence, it is quite limited.
It takes two optional parameters: the namespace where to look for (I haven't found a way to avoid that), and the name of the parent class -> :Children [!] {namespace} {parent-class}.
The command tries to cache as much information as possible. Hence, when pertinent information changes in the ctags database, the cache must be updated. It is done by banging the command -> :Children!
I don't think vim is the correct tool to list all child classes. Instead, we'd better use the doxygen to generate documentation for the source code. Although the doxygen needs some time, we can use the document/diagrams for all classes, which is clear and fast.

Change header with macro in Word Template on SharePoint

I'm working on a Word template that the user can access from Sharepoint.
In this template I have made a custom ribbon with custom ui editor.
I want the users to be able to choose a header and a footer.
For this I have already made 2 different headers (1 with fields and 1 without) and saved them in the template.
So when I want to insert a header I can select them like this: Insert --> Header --> scroll all the way down to 'Template' and select one of them. This works perfect. I've recorded a Macro of this process so I am able to use this on my custom ribbon.
the macro looks like this:
Sub Header()
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
ActivePane.View.Type = wdOutlineView Then
ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Application.Templates( _
"http://spf.mysite.be/Shared%20Documents/Template.dotm"). _
BuildingBlockEntries("Header").Insert Where:=Selection.Range, _
RichText:=True
Selection.MoveDown Unit:=wdLine, count:=4
Selection.Delete Unit:=wdCharacter, count:=1
Selection.Delete Unit:=wdCharacter, count:=1
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
End Sub
The problem:
When I open the template from sharepoint this macro doesn't work anymore.
I think this is because Word changes the linked template. when I go to the developer tab and click on 'Document Template' the linked template is the following: 'C:\Users\xxx\AppData\Local\Temp\TemplateATA-8.dotm' (the 8 changes to a 9 the next time I open the template from SharePoint.)
When i work localy and change the link to the local location, there is no problem.
Can someone please help me?
Thanks
Nina
(I'm using Word 2013, but also older versions of Word have to be able to use the document.)
Problem solved. I changed the link to: Application.Templates( _
ActiveDocument.AttachedTemplate.FullName). _
Now it works perfectly!!