Question regarding HTML sitelet page definition

23 views
Skip to first unread message

Dmitri Nesteruk

unread,
Apr 18, 2011, 11:08:07 AM4/18/11
to websh...@googlegroups.com
I'm working with HTML sitelets and am specializing Page.Default with my own Body content. Now, the Body property is defined as seq<Element<Web.Control>> and this is a major problem for me: I just cannot see how I could possibly get my data to accomodate this properly. The problem is that, typically, examples feed this variable with something like Body [new Client.SomeControl()] which is fine if SomeControl returns an IPagelet. The problem is that I totally do not want this: the result of the control function I have is not a single element, but a list of elements, such as 
[
  P [Text "something"]
  P [Text "something else"]
]
So the problem is that, for the life of me, I cannot figure out how to stick this into a Body tag and specify it as Page.Body.
Help is therefore much appreciated!

Anton Tayanovskyy

unread,
Apr 18, 2011, 11:22:57 AM4/18/11
to websh...@googlegroups.com
Hi,

The following type-checks fine:

{ Page.Default with
Body =
[
P [Text "HELLO"]
P [Text "HELLO"]
]
}

Here P is IntelliFactory.Html.Tags.P that is the server-side P. This
will generate <p> tags in the HTML directly.

The system will NOT allow you to include client-side P in the Body,
and for good reason: doing that would interleave client and
server-side code without giving the compiler any chance to unravel
them. If you are generating client-side dynamic code, it has to pass
through the control boundary:

{ Page.Default with
Body =
[
P [MyControl()]
]
}

Where MyControl is an IPagelet; MyControl constructor is called on the
server side, the object serialized, passed to the page, de-serialized
in JavaScript on the client-side, and its body constructed with DOM.
In the HTML source all you see is a placeholder under <p>.

Hope this helps.


Thanks,

Anton

--
Kind Regards,
Anton Tayanovskyy

WebSharper™ - type-safe JavaScript in F#
http://intellifactory.com

Dmitri Nesteruk

unread,
Apr 18, 2011, 11:32:51 AM4/18/11
to websh...@googlegroups.com
Okay, but my problem is I don't want a placeholder! I mean, here's what I want

<body>
<i></i>
<u></u>
</body>

Something like that. So I define my control to return a 

Body [ I []; U []]

(or something to that effect). Now I want to render exactly that without any extra wrapper tags. Can I do it, and if so, how?

Anton Tayanovskyy

unread,
Apr 18, 2011, 11:42:02 AM4/18/11
to websh...@googlegroups.com
Hi,

Use:
{ Page.Default with
Body =
[
Tags.I [Text "HELLO"]
Tags.B [Text "HELLO"]
]
}

Do not use Control types if you want to generate server-side HTML.

Yes, Control types are limited to generating a single DOM node.


Thanks,

Anton

--

Dmitri Nesteruk

unread,
Apr 18, 2011, 12:05:13 PM4/18/11
to websh...@googlegroups.com
Okay, so I just tried doing what you suggest, i.e. putting the two tags in there. As soon as I do that, I get the 'command exited with code -1'.
But even so, I removed the 'control' business completely (if it's server-side, why is it part of the offline sitelet template?) and replaced it.
So now I have

    let Page title body =
      PageContent <| fun context ->
        { Page.Default with 
            Doctype = Some "<!DOCTYPE html>"
            Title = Some title
            Body = body
            Head = ... // and so on

Now, I write something like

  let Index =
    View.Page "test" (Client.Index())
    |> Sitelet.Content "/index" Action.Index

with Client.Index() returning a list of elements.
Even so, I still get the following (rather predictable problem):

Error 1 The type 'Html.Element list' is not compatible with the type 'seq<Element<Web.Control>>' C:\My Dropbox\Projects\StockPricingSystem\DiffControlPanel\Main.fs 110 29 DiffControlPanel

Anton Tayanovskyy

unread,
Apr 18, 2011, 12:08:00 PM4/18/11
to websh...@googlegroups.com
Without a complete code listing we cannot reproduce your problem. My
guess is that you might be using client-side combinators again. Do not
open IntelliFactory.Html and IntelliFactory.WebSharper.Html. Make sure
you are using IntelliFactory.Html.Tags.P.

--A

--

Anton Tayanovskyy

unread,
Apr 18, 2011, 12:16:05 PM4/18/11
to websh...@googlegroups.com
Here is the one way to put the code in:

https://gist.github.com/a376b5b2d09d99b1637e

Is it clear why it is impossible to include client-side HTML elements
within server-side HTML elements or do I have to elaborate more?

--A

Dmitri Nesteruk

unread,
Apr 18, 2011, 12:16:34 PM4/18/11
to websh...@googlegroups.com
Ahh, okay, I get you. I removed those references and it's not looking right.
But now I have another problem: lots of my code hinges on Attr.NewAttr and Tags.NewTag, but after removing the namespaces, I no longer get those members.
What is the right way of getting these declarations back in?

Anton Tayanovskyy

unread,
Apr 18, 2011, 12:18:30 PM4/18/11
to websh...@googlegroups.com
If you keep client-side and server-side modules separate, you can open
IntelliFactory.WebSharper.Html in client-side modules and open
IntelliFactory.Html in server-side modules and keep using Attr.NewAttr
as before. Just make sure those don't mix. Hope it helps. --A

--

Dmitri Nesteruk

unread,
Apr 18, 2011, 12:24:58 PM4/18/11
to websh...@googlegroups.com
Well I'm working with offline HTML sitelets, so the assumption is that there is no 'server' side to speak of. On the other hand, I do need to emit my own tags and attributes that are not part of the standard vocabulary. Is it possible?

Anton Tayanovskyy

unread,
Apr 18, 2011, 12:36:16 PM4/18/11
to websh...@googlegroups.com
It is of course possible to define your own tags, both server and client side.

Please make sure you understand this: using offline HTML sitelets in
no way eliminates the distinction between server-side and client-side.
Maybe it might be better called static vs dynamic.
IntelliFactory.Html.* tags generate HTML statically, before the
browser starts - during compilation, in fact - for offline sitelets.
IntelliFactory.WebSharper.Html.* tags generate DOM nodes in the
browser and therefore support events and other dynamic features. These
cannot be mixed, except through the Control indirection I described
above.

Thanks,

--A

--

Reply all
Reply to author
Forward
0 new messages