Движок для сайта на GWTм (Google Web Toolkit)

6 Июн
2012

Как-то несколько лет назад мне предложили написать веб-интерфейс к программе, написанной на java. Решили, что серверная часть будет в виде xmlrpc. В принципе реализация могла быть любой, но так как особых мыслей по этому поводу у меня не было, я спросил, на чем лучше делать, услышал в ответ GWT. Параллельно работая над проектом и вникая в этот самый GWT, понял насколько приятна эта технология для разработчика. Код программы пишется на java, с моей точки зрения один из наиболее удобных ООП языков, позволяющий легко работать над большим проектом даже одному разработчику. Далее некий транслятор переводит этот код в JavaScript, который уже запускается в браузере пользователя и работает там ну очень быстро, чего не скажешь о десктопных java приложениях. Также обнаружились и другие плюсы этой технологии.

  1. Так как программа исполняется полностью на стороне клиента, очень сильно разгружается сервер, фактически все сводится к размещению обычного html.
  2. Концепция «виджетов». Зайдя на сайт, пользователь больше не обновляет страницу полностью, везде где надо виджеты обновляются сами, что также уменьшает трафик.


Все это натолкнуло меня на мысль создать движок для сайтостроения или даже CMS на GWT, так как после гугления я так и не нашел уже готового аналогичного решения.

Ключевыми фичами движка, помимо преимуществ GWT, должны были стать:
  1. Поддержка шаблонов на html, чтобы можно было легко менять дизайн не затрагивая само приложение.
  2. События с сервера. Один пользователь что-то меняет, посредством событий эти изменения отображаются у других пользователей насколько это возможно быстро.
  3. Использование adsense вместе с GWT


Сначала разработка этого движка имела чисто теоретический интерес и велась не особо быстро. Но тем не менее спустя некоторое время удалось достичь некоторых результатов. Поддержка шаблонов реализовалась в том, что виджеты сайта представляют из себя теги, которые можно использовать в любом удобном для этого месте. Пример тега:

<div id="dvijokw" name="widget_name" dwid="widget_instance_unique_id(not required)" ></div>


Которые начинают работать после подключения js-ки. В остальном страницы — обычный html.

В коде виджет выглядит например таким образом:

public class Auth extends SubPanelsDwidget {

	private TextBox login;
	private PasswordTextBox pass;
	... объявление свойств

	public Auth(){
		//виджет может иметь шаблон, здесь указывается откуда его брать
		super("tmpl/widgets/auth/auth/auth.html");
	}
	
	//любой нужный код ...
	public void setFocus(boolean focused){
		login.setFocus(focused);
	}
	...

	@Override
	protected void beforeSubPanelsLoading() {
		//эта функция вызывается до загрузки шаблона
		//здесь нужно проинициализировать поля используемые
		//при загрузке шаблона
		...
		this.login = new TextBox();
		this.login.addKeyDownHandler(loginkdh);
		...
	}
	
	// можно также наобъявлять лисенеров чтобы другие виджеты
	// могли реагировать на события этого виджета
	public void addLoginedListener(CustomEventListener listener){
		...
	}

	@Override
	protected Widget genSubWidget(String dwname, ArrayList<DBObject> params) {

		//тут происходит наполнения шаблона конпками полями ввода и т.п.
		//которое находится, как правило, в полях данного виджета
		if( dwname.equals("login") ) return this.login;
		else if ...
		else return null;

	}
}


Шаблон виджета выглядит например таким образом:

<div class="authcomp">
Логин<div class="authfield" id="dw" dwname="login"></div>

Пароль<div class="authfield" id="dw" dwname="pass"></div>

<div class="dwbutton" id="dw" dwname="dologin"></div>
<div class="dwbutton" id="dw" dwname="cancel"></div>
</div>
Везде между <div class=»authfield» id=»dw» dwname=»login»></div> тегами может быть любой произвольный html код и теги виджетов. В эти дивы потом будет помещено то, что вернет функция genSubWidget для строчки указанной в dwname атрибуте.

Поддержка событий с сервера организовалась в виде long-poll запросов. В коде это выглядит приемрно так:

	Resources.getInstance().db.addEventListener(tagsdbo, new DataBaseEventAdapter(){

	@Override
	public void objectAdded(DataBaseEvent evt) {
	    ...
	    //здесь можно отреагировать на пришедшее сообщение
	    //в данный момент я использую объектно ориентированную БД
	    //поэтому все события сводятся к этим трем, но в принципе
	    //можно использовать любые событя
	}

	@Override
	public void objectModifyed(DataBaseEvent evt) {
	    ...
	}

	@Override
	public void objectDeleted(DataBaseEvent evt) {
	    ...
	}});


Все это позволяет легко внедрять паттерны MVC и MVVM.

Также оказалось, что необязательно иметь серверную часть на java, можно использовать любую серверную технологию для организации RPC. В данный момент у меня используется rpc на php с простейшим бинарным протоколом, задача которого быть очень быстрым и простым в реализации. Все что возможно передать — это строки, таблицы и массивы, а также любая комбинация произвольной вложенности всего этого. Дальнейшие преобразования к числам и т.п. происходят уже в коде. Посмотреть как все это работает можно на примере сайта find-home.ru

Пока что виджетов для реализации CMS не существует для моего движка, так как он до сих пор находится в режиме разработки. На данный момент я сосредоточен над работой над вышеуказанным сайтом. Движок лицензирован под GNU GPL, хостится на code.google.com/p/dvijok/, но на данный момент там лежит довольно старая версия, позже планирую выложить туда свежую версию после отделения движка в отдельный модуль. Сейчас движок и сайт по аренде недвижимости без посредников слиты в один модуль для простоты разработки.

Единственный недостаток который я вижу в этой технологии: то, что содержание виджетов не видится поисковыми роботами, что затрудняет индексацию, но у гугла есть выход для таких ситуаций, у них есть возможность указать роботу на некий урл который отрендерит для него страницу, а пользователи будут продолжать пользоваться полностью динамическим приложением.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх