Strongly Typed from Model to View

Discussion about the open-source Phalanger [?] project.

Strongly Typed from Model to View

Postby tleslie » August 3rd, 2012, 4:50 am

Can Phalanger, using it to eval php for a view,
have strong type between model and view, that is, not have
ViewData $Model

but have it be like asp.net mvc3 of:
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<HowMVCWorks.Models.Zoo.Monkey>" %>

So i can directly access the object in the view (as strong typed).
And this would be by using Phalanger to allow php as a viewengine in mvc3.

What i would like to do is have php as the view in a mvc3 environment on Windows,
and linux (via mono), but have the model data in the view strongly typed (access).
-tl
tleslie
 
Posts: 32
Joined: August 3rd, 2012, 4:42 am

Re: Strongly Typed from Model to View

Postby Jakub Misek » August 3rd, 2012, 1:58 pm

Hi,

Phalanger allows you to make View in PHP, and the rest of application in another .NET language.

There is one example in F# :) https://github.com/robertpi/PicoMvc/tre ... c.PhpViews

Currently I'm not sure it is able to fully cooperate with master pages. I only know you can write codebehind of .aspx page in PHP.

Typical approach is to render PHP view by yourself. Any variable can be passed from C# to PHP, so you can access them in PHP.
Jakub Misek │ DEVSENSE s.r.o. | @misekjakubjakub@devsense.com
User avatar
Jakub Misek
 
Posts: 2092
Joined: January 4th, 2012, 2:42 pm
Location: Prague

Re: Strongly Typed from Model to View

Postby tleslie » August 3rd, 2012, 2:28 pm

When you say "render PHP view by yourself" you are referring to using
DynamicCode.Eval(..) ? If this is the case, does the "php code" have to be
only php code, or can it have reference to .net in that php code?
In all the examples online i see of Phalanger with MVC, and php view,
it is done in away that intellisense wouldn't work in the php (in vs2010\)
because the $Model (for example) wouldn't be typed.
Optionally, is there another way to call a php view from the controller,
that isn't DynamicCode.Eval?
Thanks, I will check out the example as well.

-tl

Jakub Misek wrote:Hi,

Phalanger allows you to make View in PHP, and the rest of application in another .NET language.

There is one example in F# :) https://github.com/robertpi/PicoMvc/tre ... c.PhpViews

Currently I'm not sure it is able to fully cooperate with master pages. I only know you can write codebehind of .aspx page in PHP.

Typical approach is to render PHP view by yourself. Any variable can be passed from C# to PHP, so you can access them in PHP.
tleslie
 
Posts: 32
Joined: August 3rd, 2012, 4:42 am

Re: Strongly Typed from Model to View

Postby Jakub Misek » August 3rd, 2012, 2:47 pm

Definitely not Eval. Eval should not be used, if you have the php file on disk.

If you have .php file in your website, just call it from C# code
Code: Select all
PHP.Core.ScriptContext.CurrentContext.Include("file.php", false);


Since PHP request has some lifecycle (begin/end), you should enclose all these PHP inclusions within single RequestContext object
Code: Select all
using (var request_context = RequestContext.Initialize(ApplicationContext.Default, HttpContext.Current)){ ... }
This will just cleanup PHP objects properly at the end.

You can pass C# objects to PHP by storing them into PHP globals (then you don't have intellisense, because it is all dynamically typed), or you can create C# container class. E.g.:
Code: Select all
public class ModelData
{
    [ThreadStatic] private ModelData data;
    public static void SetInstance(ModelData data){ this.data = data; }
    public static ModelData GetInstance(){ return data; }

    public string xxx;
    // ...
}

Place declaration of this class into some DLL, and add reference to this DLL into web.config/<phpNet>/<classLibrary>.

In C# you will call ModelData.SetInstance( new Modeldata(){ ... } );
In PHP you can then
Code: Select all
$model = ModelData::GetInstance();
$model->...

You can play around with this approach a little. IntelliSense in PHP is a matter of Phalanger Tools integration, so if you miss a feature, just note it at viewforum.php?f=10 .

IntelliSense of PHP code in C# project can only work if you compile your PHP code in so-called Pure mode (http://wiki.php-compiler.net/Pure_mode).
Jakub Misek │ DEVSENSE s.r.o. | @misekjakubjakub@devsense.com
User avatar
Jakub Misek
 
Posts: 2092
Joined: January 4th, 2012, 2:42 pm
Location: Prague

Re: Strongly Typed from Model to View

Postby tleslie » August 7th, 2012, 3:42 am

I have followed you advise, and now have a mvc3 project with phalanger
php view engine.
I have accessed (static type) class, but this is where i have my last issue.
In your example, you have the
ModelData Class, but you have static methods accessing "this".
When I access the class in php, i am accessing (in my test),
a static class method, so any user using the mvc3 web site would be
sharing that data, and sometimes that is useful,
but mostly, you want the instance of that ModelData class to be private
and used (rendered in view) in just that session (of the view & model collaboration). So this is the missing piece.
I get the request to View a page, I calc my data, now i have to
instantiate a class "ModelData" with data just for this session,
and introduce it to the PHP rendered page.
I am not clear on how to do this.
Am i assigning a modeldate (dateview) context in the main block below?

using (var request_context = RequestContext.Initialize(ApplicationContext.Default, HttpContext.Current)){ ... }

or? just not sure how to direct the php rendered above to use a instance
I supply , of the model data.

Thank for all your help Jakub, your support this product very well,
I feel my 150$ (to license Phalanger vs2010 tools, once trial expires) will now be well worth it.



-tl
tleslie
 
Posts: 32
Joined: August 3rd, 2012, 4:42 am

Re: Strongly Typed from Model to View

Postby Jakub Misek » August 7th, 2012, 7:58 am

Yes, you can pass an instance too. This would be also little bit cleaner solution.

Pass a value from C# to PHP:
You can simply do anything in context of PHP script. To pass a value from C# into PHP, I would use
Code: Select all
dynamic globals = ScriptContext.CurrentContext.Globals;
globals.model = value;
which will pass value to PHP global variable $model. (more interoperability tricks at http://www.php-compiler.net/blog/2012/n ... langer-3-0)

Read value in PHP so IntelliSense will be aware of its type:
Then you have the value in PHP, but IntelliSense still can't find the type information. Since IntelliSense understands PHPDoc, you can create simple PHP function which will 'annotate' your variable:
Code: Select all
/**
 * Gets given value.
 *
 * @return MyCSharpCode\MyModel
 */
function GetModel()
{
    global $model;
    return $model;
}

GetModel() is then known by IntelliSense that it returns an instance of object MyCSharpCode\MyModel.
Code: Select all
GetModel()->...

As noted before, Assembly containing definition of MyCSharpCode\MyModel must be loaded in context of PHP script. So you have to add the reference to <phpNet><classLibrary><add ... />
Jakub Misek │ DEVSENSE s.r.o. | @misekjakubjakub@devsense.com
User avatar
Jakub Misek
 
Posts: 2092
Joined: January 4th, 2012, 2:42 pm
Location: Prague

Re: Strongly Typed from Model to View

Postby tleslie » August 8th, 2012, 6:44 pm

This worked for me , thanks!
however, i actually did it the following:

instead of the PHPDoc way, i just did

$xxx = new MyCSharpCode\MyModel;
$xxx = $model;

$xxx->...;

Now if the object MyModel had a constructor of significance, this would not
be a great way to "force" intellisense, however, for my use, MyModel
is just properties mostly, so this works well for me,
however, do you see anything wrong with this way? (other then if
there is a significant constructor doing essentially wasted work?).

Also, in order to get access to objects in my immediate project, i still
had to include the projects dll in the phpNet <classLibrary> in web.config,
is that right? i would have assumed "internal" classes would always be
available? i.e. Phalanger would automatically refer to the dll created by
the project, so internal types could be used in the php.



-tl
tleslie
 
Posts: 32
Joined: August 3rd, 2012, 4:42 am

Re: Strongly Typed from Model to View

Postby Jakub Misek » August 8th, 2012, 7:16 pm

It is just an overhead for runtime, in general the solution is ok, just to bluff IntelliSense. (However if we get IntelliSense smarter in future, it would assume the variable was overwritten by $model and will ignore its previous value)

You have to include a DLL reference into <classLibrary> in two cases:
- you would like to see IntelliSense of a class defined in the DLL
- you would like to instantiate class defined in the DLL in runtime, or call a static method on a class defined in the DLL
Jakub Misek │ DEVSENSE s.r.o. | @misekjakubjakub@devsense.com
User avatar
Jakub Misek
 
Posts: 2092
Joined: January 4th, 2012, 2:42 pm
Location: Prague

Re: Strongly Typed from Model to View

Postby tleslie » August 28th, 2012, 10:52 am

I have been doing this my my, with declaring the var, then reassign,
and the intellisense works,
i just tried your way with the "PHP docs comment"
it doesn't work. Any ideas?

-tl



Jakub Misek wrote:Yes, you can pass an instance too. This would be also little bit cleaner solution.

Pass a value from C# to PHP:
You can simply do anything in context of PHP script. To pass a value from C# into PHP, I would use
Code: Select all
dynamic globals = ScriptContext.CurrentContext.Globals;
globals.model = value;
which will pass value to PHP global variable $model. (more interoperability tricks at http://www.php-compiler.net/blog/2012/n ... langer-3-0)

Read value in PHP so IntelliSense will be aware of its type:
Then you have the value in PHP, but IntelliSense still can't find the type information. Since IntelliSense understands PHPDoc, you can create simple PHP function which will 'annotate' your variable:
Code: Select all
/**
 * Gets given value.
 *
 * @return MyCSharpCode\MyModel
 */
function GetModel()
{
    global $model;
    return $model;
}

GetModel() is then known by IntelliSense that it returns an instance of object MyCSharpCode\MyModel.
Code: Select all
GetModel()->...

As noted before, Assembly containing definition of MyCSharpCode\MyModel must be loaded in context of PHP script. So you have to add the reference to <phpNet><classLibrary><add ... />
tleslie
 
Posts: 32
Joined: August 3rd, 2012, 4:42 am

Re: Strongly Typed from Model to View

Postby Jakub Misek » August 28th, 2012, 12:41 pm

Just one idea, you need latest Phalanger Tools; sorry I didn't mention ... Currently it can be downloaded as a part of Setup archive (at http://phalanger.codeplex.com/releases/view/93446) - in subfolder is phalanger.vs.vsix file. We're going to upload new version on VisualStudio gallery today.
Jakub Misek │ DEVSENSE s.r.o. | @misekjakubjakub@devsense.com
User avatar
Jakub Misek
 
Posts: 2092
Joined: January 4th, 2012, 2:42 pm
Location: Prague

Next

Return to Phalanger project

Who is online

Users browsing this forum: No registered users and 27 guests

User Control Panel

Login

Who is online

In total there are 27 users online :: 0 registered, 0 hidden and 27 guests (based on users active over the past 5 minutes)
Most users ever online was 511 on April 27th, 2024, 10:11 pm

Users browsing this forum: No registered users and 27 guests