我目前正在研究一个基于Laravel 4框架构建的cms。 我正在尝试构建一个类似于 Pyro CMS 的插件系统,其中模块视图可以使用 Blade 模板系统包含在页面视图中。
我正在构建一个联系表单插件,如果成功提交,会将用户重定向到给定的 URL,或者只是重定向回现有页面。
我的联系表单类的代码是:
class Contact {
public static function form($params)
{
//get params and execute relevant logic here
$redirect = isset($params['redirect']) ? $params['redirect'] : Request::url();
$data = Input::all();
if($data)
{
// Run validation and send message here
return Redirect::to($redirect)
}
return View::make('contact_form_view');
}
}
有一个页面控制器将根据使用的路由显示适当的页面视图,其想法是用户可以将联系表单拖放到任何页面模板中,并通过从模板视图中调用表单函数轻松自定义它,如下所示
<html>
<head>
</head>
<body>
{{ Contact::form(array(
'to' => 'myemail@mydomain.com',
'view' => 'contact_form_1',
)) }}
</body>
</html>
除了重定向之外,这一切都可以正常工作。成功提交表单并发送邮件后,页面将刷新并显示以下消息来代替联系表单
HTTP/1.0 302 Found Cache-Control: no-cache Date: Tue, 17 Sep 2013 09:14:16 GMT Location: http://localhost:8888/my_initial_route Redirecting to http://localhost:8888/my_new_route.
大约 2 秒后,重定向发生,浏览器被重定向到用户在 $params 数组中提供的任何路由,如果未提供重定向,则重定向到当前页面,如上例所示。
关于它为什么要这样做的任何建议,以及任何解决方案,都会很棒。
谢谢!
编辑:
以下是我为什么采取上述方法的简要概述,这可能有助于理解问题:
该项目的一个要求是,最终将使用 cms 的开发人员可以通过单击"添加页面"按钮通过 cms 控制面板创建无限数量的页面。 这个想法是,我们不会为我们想要创建的每个新页面编写新的页面控制器。有了这个,我介意我有以下路线:
Route::any('{page_slug}/page', array('as' => 'frontend.page', 'uses' => 'FrontendPagesController@display_page'))->where('page_slug', '[-A-Za-z0-9_-]+');
大大瘦display_page
功能是:
public function display_page($slug)
{
$page = PagesModel::getPageBySlug($slug);
return View::make($page['view_name']);
}
有了这个,用户可以通过单击按钮创建一个页面,为其命名和一个 slug,然后应用程序可以显示该页面和相应的视图 - 在创建页面时定义 - 而无需添加任何新的路由、控制器等。
当用户希望在页面中包含联系表单时,就会出现问题。我们如何知道他们是否会添加表单,他们将使用哪些字段以及需要什么验证?我需要一种方法,能够在任何页面中添加完全自定义的联系表单,而无需开发人员触摸cms代码。我的解决方案是上面给出的方法:开发人员将标签放入视图中,并向函数传递一些参数,这些参数自定义表单功能。
Contact::form()
函数有点像窗体的控制器。它获取并返回包含 from html 的视图,处理提交并根据结果返回成功/错误消息。
现在我不一定需要使用上述方法,但我需要一种方法将联系人表单控制器与页面控制器分开,并且开发人员能够在不接触 cms 后端代码的情况下将表单添加到任何页面。
对此的任何想法都会很棒。
您应该从控制器调用redirect
,而不是从视图中调用。发生这种情况是因为您已经在视图中并且它是可见的,因此,如果您以某种方式可以隐藏它(正文),那么在重定向发生之前它将不可见。
但是,你做错了,anti-pattern
,IMO。使用控制器做出决定,视图应仅用于演示。这是MVC
框架中最基本的规则。
当您在视图中调用函数时,它应该返回然后显示的 HTML。 例如,当您调用{{ Url::to('foo') }}
时,它会生成 http://yoursite.tld/foo。
当你调用{{Contact::form(...)}}
时,它应该输出HTML。 当您返回 View::make(...)
时,您将返回 HTML。 当你返回Redirect::to(...)
时,你返回一个Laravel对象,Laravel路由器将其解析为重定向标头。
重定向几乎必须由路由对象或控制器调用。 如果您的表单提交由控制器处理,请将重定向放在那里。
刚刚遇到了同样的问题,降级到"4.0.*"并且已修复。
看起来这是一个 4.1.x 问题。
降级步骤
将 composer.json 更改为:
"require": {
...
"laravel/framework": "4.0.x",
...
}
编辑应用.php - "控制器"别名
'Controller' => 'IlluminateRoutingController',
应该成为
'Controller' => 'IlluminateRoutingControllersController',
我不得不删除这些服务提供商
'IlluminateRemoteRemoteServiceProvider',
'IlluminateExceptionLiveServiceProvider',
编辑:
我已经在 Github 上打开了一个关于这个问题的问题,早些时候泰勒修复了它。做一个作曲家更新,你应该没事。
简单的方法:
header('Location: '.route('clients.create'));