如何生成一个链接到一个页面与请求变量不在url中的symfony2


How to generate a link to a page with a request variable not in the url in symfony2

我使用prism。Symfony2

在prism中,您必须按ID查询文档。例如,在我的twig模板中有如下内容:

 <h3><a href="{{ path('postDetail', {'id': post.getId, 'slug': post.slug, 'ref': ctx.maybeRef}) }}">{{ title }}</a></h3>

生成这个url:

/U3zRuQEAADoAGg7D/slug-of-document

我在控制器中获得十六进制id,可以成功查询页面。然而,使用ID并不是很人性化。我想生成一个url,可以在请求中传递id变量,但在url中不可见。这可能吗?

为澄清,这里是通过过程的代码。我有一个按标题列出所有博客文章的页面:

<article class="blogEntry">
    {% if date is defined %}
        <small>{{ date|date("m/d/Y") }}</small>
    {% endif %}
    {% if title is defined %}
        <h3><a href="{{ path('postDetail', {'id': post.getId, 'slug': post.slug, 'ref': ctx.maybeRef}) }}">{{ title }}</a></h3>
    {% endif %}
    {% if author is defined %}
        <small class="blogAuthor">{{ author }}</small>
    {% endif %}
    {% if excerpt is defined %}
        {{ excerpt|raw }}… <a href="{{ path('postDetail', {'id': post.getId, 'slug': post.slug, 'ref': ctx.maybeRef}) }}">Continue Reading »</a>
    {% endif %}
</article>

当标题被点击时,它会转到pageDetail Action:

/**
     * @Route("/blog/{id}/{slug}", name="postDetail")
     * @Template()
     */
    public function postDetailAction($id, $slug)
    {
        $ctx = $this->get('prismic.context');
        $post = $ctx->getApi()->forms()->everything->ref($ctx->getRef())->query('[[:d = at(document.id, "'.$id.'")]]')->submit();
        $post = $post->getResults();
        if ($post) {
                return array(
                    'ctx' => $ctx,
                    'bgImages' => $backgroundImages,
                    'siteInfos' => $siteInfos,
                    'post' => $post
                );
        } 
        throw $this->createNotFoundException('Document not found');
    }

我想要更像这样的东西,所以id在请求中,可以用于查询,但不可见:

    /**
    * @Route("/blog/{slug}", name="postDetail")
    * @Template()
    */
    public function postDetailAction($slug)
    {
       $request = $this->getRequest();
       $request->query->get('id');
       $ctx = $this->get('prismic.context');
       $post = $ctx->getApi()->forms()->everything->ref($ctx->getRef())->query('[[:d = at(document.id, "'.$id.'")]]')->submit();
       $post = $post->getResults();
       if ($post) {
          return array(
              'ctx' => $ctx,
               'post' => $post
          );
       } 
    throw $this->createNotFoundException('Document not found');

}

我已经尝试过了,但是我得到一个未定义的变量异常,使我认为我没有在请求中正确发送ID。

我不认为这是可能的,因为ID需要以某种方式表示,即使不是来自这个特定的页面。我只是想提出这个问题,看看是否可能。

为什么不使用简单的js提交一个隐藏的表单?

jquery-code
<span class="link">{{ title }}</span>
<form class="fooForm" method="POST" action="{{ path('postDetail', {'slug': post.slug, 'ref': ctx.maybeRef}) }}" style="display:none">
        <input name="id" type="hidden" value="{{post.getId}}">
</form>


<script>
    $(document).on("click",".link",function(){
        $('.fooForm').submit();
    })
</script>

在控制器中输入:

   $request = $this->getRequest();
   $id=$request->get('id');

但是你的url只能处理post-request,所以它只能通过表单访问,这不是很酷,这不是很友好,但这似乎是你想要的

我认为这是不可能的,因为HTTP方法是GET,你应该通过url传递变量。

也许有一个解决方案,如果你用POST方法做请求。您可以设置表单,或者在用户单击链接时使用jQuery创建POST请求。这样,您就可以将变量传递给控制器。但是如果所有的链接都需要这个id变量,这就不是一个很好的方法了。也许如果你写一个全局JavaScript函数来生成链接,并使用该函数而不是{{ path('path_name') }}

另一种方法是在触发控制器动作后立即重定向用户。您使用GET方法传递变量,并且id在url中。在触发的操作中,您将该变量保存到会话中,并将用户重定向到另一个操作,其中url中不需要该变量。然后,您可以通过获取会话变量在新控制器中使用id。这也不是一个好的解决方案,因为你必须创建许多冗余的操作。

如果只在某些页面中需要,我建议使用JavaScript版本,或者您应该考虑不隐藏id。也许不值得这么做