Laravel - 从视图中调用重定向::to()



我目前正在研究一个基于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'));

最新更新