Сначала о том, почему я решил так сделать. Во-первых, изучение любого фреймворка занимает время, больше или меньше, и в конце-концов натыкаешься в самых неожиданных местах на "тупые" ограничения, которые потом попробуй обойди. При недостаточном знании фреймворка, к тому же, велика вероятность, что он будет делать ненужную в данном проекте работу.
Также проще написать велосипед с нужной рамой, нужными покрышками, нужными ободами и тормозной системой, чем брать чужой велосипед и переделывать под то, что нужно.
Ловите пример. Оставил, по возможности, только репрезентативные куски. Также сразу оговорюсь, что пока что не очень обращал внимание на дыры в безопасности :)
В контроллере, ajaxовый и обычный вызов :
<?php
class UserController extends Controller{
public function edit(){
if($this->user->isAuthenticated()){
$this->templator
->defineViewForContent('main', 'user/edit')
->addVar('pagetitle', 'User Edit Page')
->addVar('finished_registration', !$this->user->get('unfinished_registration'))
->renderTemplate('homepage');
}else{
}
}
public function register_ajax(){
$this->loadModel('user_register_ajax');
}
public function search(){
$model = $this->loadModel('project_search');
$this->templator
->defineViewForContent('main', 'project/search')
->addVar('pagetitle', 'Project search...')
->addVarsArray($model->getData())
->renderTemplate('homepage');
}
}
<?php
class UserRegisterAjaxModel extends AjaxModel{
public function __construct(){
$this->email = Request::$post['email'];
$this->confirmation_code = Request::$post['confirmation_code'];
$this->password = Request::$post['password'];
parent::__construct();
}
public function register(){
$user = User::createUser($registration);
if(empty($registration['inviter_id']) && empty($registration['school_id'])){
$user->addRole(User::UNCONFIRMED_USER_ROLE);
}else{
$user->addRole(User::CONFIRMED_USER_ROLE);
}
if(isset($registration['school_id'])){
$user->addRole(User::SCHOOL_USER_ROLE);
}
$user->save();
$this->user->login($this->email, $this->password);
$templator = Templator::getInstance();
$templator->addVar('login_email', $this->email)->addVar('login_password', $this->password);
file_put_contents('registration_data.txt', $templator->renderEmailTemplate('registration_confirmation'));
}
}
}
}
Собственно сама модель.
<?php
class AjaxModel extends Model{
protected $action;
protected $result;
public function __construct(){
parent::__construct();
sleep(0);
$this->action = Request::$post['action'];
if(($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') || empty($this->action)){
die;
}
$this->result = array(
'finished'=>false
,'action'=>$this->action
);
if(($this->action !== '__construct') && method_exists($this, $this->action)){
$reflection = new ReflectionMethod($this, $this->action);
if($reflection->isPublic()){
$this->{$this->action}();
}
}else{
Logger::logErrorMessage('Tried to call uncollable method');
}
$this->result['finished'] = true;
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($this->result);
}
}
Шаблоны у меня просто на PHP. Поэтому выглядит это как-то так:
<div style="float: right; border: 1px solid blue; border-radius: 0px 0px 5px 5px; padding: 7px; border-top: none; margin-top: -22px"><?php $this->renderView('common/login_form');?></div>
<?php $this->renderView($main_content);?>
</div>
<script src="<?=$site_url?>js/bootstrap.min.js"></script>
<script src="<?=$site_url?>js/typeahead.bundle.min.js"></script>
</body>
Т.е. мой Templator просто делает доступным в шаблоне то, что было добавлено в Templator с помощью Templator::addVar() или подобных методов. И не надо пугаться, это просто тестовый шаблон, поэтому CSS прямо там, в HTML :)
Кроме того, есть еще кусок, который позволяет легко переводить сайт на несколько языков. В результате для переводящего человека это выглядит так:
https://www.youtube.com/watch?v=RNVEFAPsDLwВот. Теперь очередь вашей критики :)