Зачем?
Клиентскую часть в веб-приложениях принято создавать на JavaScript. Я считаю, что большинство разработчиков с огромным удовольствием бы отошли от этого правила и воспользовались своим любимым server-side языком. Ну что же, команда
MIX Online предоставила любителям динамических языков такую возможность, подробнее об этом можно прочитать в “
Проект Gestalt – пишите на Ruby, Python и XAML прямо в HTML на стороне клиента”. Ниже я предлагаю создать нечто подобное, но уже своими силами.
С помощью чего?
Посмотрев несколько примеров мне стало ясно, что реализован Gestalt на Silverlight + Dynamic Languages Runtime. Далее я прикинул, а на сколько сложно создать нечто своими руками? И сразу же решение: Silverlight умеет взаимодействовать с DOM – значит я смогу получить код и интерпритировать его – дело за малым – реализация.
Приступим
Нам понадобятся:
- Visual Studio >2008SP1 (при желании можно и другие IDE или средства редактирования текста)
- Silverlight >2.0 Tools
- Dynamic Languages SDK >0.5.0 (download)
- 10 мин времени
Lets code
Открываем Visual Studio, создаём Silverlight Application, я назову проект “mygestalt”. Теперь я осознаю, что писать та надо будет совсем не много, мне понадобится экспериментальный Client-Script и его интерпритатор. Открываем страничку, на которой будет хоститься наш Silverlight, в моём случаем это mygestaltTestPage.aspx и добавляем туда наш client-side python code. Выглядеть это должно примерно так:
- <script type="python">
- def func():
- HtmlPage.Window.Alert("Hello world!")
-
- func()
- </script>
* This source code was highlighted with Source Code Highlighter.
Далее отправляемся в MainPage.xaml.cs, где будем заниматься поисками нашего скрипта:
- using System.Linq;
- using System.Windows.Browser;
-
- namespace mygestalt
- {
- public partial class MainPage
- {
- public MainPage()
- {
- InitializeComponent();
- FindAndRunScript();
- }
-
- private void FindAndRunScript()
- {
- var scripts = HtmlPage.Document.GetElementsByTagName("script");
- var pythonScript = scripts.Where(x => x.GetProperty("type").ToString() == "python").First();
- PythonEngine.Run(pythonScript.GetProperty("innerHtml").ToString());
- }
- }
- }
* This source code was highlighted with Source Code Highlighter.
Ну и реализация PythonEngine:
- using Microsoft.Scripting;
- using Microsoft.Scripting.Hosting;
- using Microsoft.Scripting.Silverlight;
-
- namespace mygestalt
- {
- public static class PythonEngine
- {
- public static ScriptScope Run(string source)
- {
- var setup = Configuration.LoadFromAssemblies(Package.GetManifestAssemblies());
- setup.HostType = typeof(BrowserScriptHost);
- setup.DebugMode = true;
- var runtime = new ScriptRuntime(setup);
- var engine = runtime.GetEngine("IronPython");
- var scope = engine.CreateScope();
- const string init = @" import clr clr.AddReference('System.Windows.Browser') from System.Windows.Browser import * " ;
-
- ScriptSource initSource = engine.CreateScriptSourceFromString(init, SourceCodeKind.Statements);
- initSource.Execute(scope);
- var script = engine.CreateScriptSourceFromString(source, SourceCodeKind.Statements);
- script.Execute(scope);
-
- return scope;
- }
- }
- }
* This source code was highlighted with Source Code Highlighter.
Запускаем приложение и видим:
В заключение
Вот у нас и получился свой собственный Gestalt, самое интересное в том, что я посмотрел его исходники и нашёл там примерно такую же реализацию. Мой проект можно найти на
http://code.google.com/p/mygestalt/. Всем спасибо!