Skip to content

[Router] added appending of new optional document fragment #12979

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 16, 2016

Conversation

rodnaph
Copy link
Contributor

@rodnaph rodnaph commented Dec 14, 2014

added a new optional parameter to the generate method for the document fragment. when specified this is appended to generated urls.

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets none
License MIT
Doc PR none

@rodnaph rodnaph force-pushed the router-generate-document-fragment branch from 8e5ec77 to 8b16335 Compare December 14, 2014 22:22
@@ -284,6 +284,11 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
$url .= '?'.strtr($query, array('%2F' => '/'));
}

// add fragment if needed
if ($fragment) {
$url .= '#'.rawurlencode($fragment);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are parameters a array and fragement a string?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it is a string, there is no natural divider that we can use to represent arrays.

@henrikbjorn
Copy link
Contributor

👍

@Koc
Copy link
Contributor

Koc commented Dec 15, 2014

ref #3910

@Koc
Copy link
Contributor

Koc commented Dec 15, 2014

Also interface changes is a BC-break

@rodnaph
Copy link
Contributor Author

rodnaph commented Dec 15, 2014

I didn't see that other ticket, thanks for referencing it. I would counter the reason it was closed though because...

  1. Fragment generation requires encoding that could gain correctness from framework help (rather than having to encode the fragment yourself)
  2. With the redirectToRoute helper in 2.6 it now remains clumsy if you are redirecting to a route with a fragment (ie. You can't so need to use generateUrl and redirect)

I also didn't think of the BC break... That's unfortunate.

@rodnaph
Copy link
Contributor Author

rodnaph commented Dec 15, 2014

I didn't realise there were special parameters (underscore prefixed) to generate, that sounds like a better approach - hopefully my reasons above will help get that other ticket reopened at least.

@rodnaph rodnaph force-pushed the router-generate-document-fragment branch from 8b16335 to 6fc2bd5 Compare December 15, 2014 10:11
@rodnaph
Copy link
Contributor Author

rodnaph commented Dec 15, 2014

I reworked the patch to use a 'special' parameter inline with other Symfony special parameters for the fragment. This removes the BC issue with the interface, though would obviously cause a problem if people were already using _fragment as a valid query string parameter.

@Tobion
Copy link
Contributor

Tobion commented Dec 15, 2014

Still a BC break as you figured yourself.

@fabpot fabpot added the Routing label Dec 18, 2014
@dawehner
Copy link
Contributor

Just a quick comment. In Drupal we have all kind of additional options, like the fragment, but also language, whether we want to render it as http or https ...
The signature looks like the following:

  public function generateFromRoute($name, $parameters = array(), $options = array());

@Tobion
Copy link
Contributor

Tobion commented Feb 3, 2015

I agree that a helper for the fragment is useful because of the encoding need. And I cannot think of a better solution than the one provided here. And the tiny BC break is negligible because it's unlikely.

Three things are missing for me to be merged:

  1. the special meaning of _fragment must be documented in the phpdoc of UrlGeneratorInterface
  2. the slash / should be decoded from the fragment just as it has been done for the query in decodes some special chars in a URL query #12223. this is also part of the rfc: "The characters slash ("/") and question mark ("?") are allowed to
    represent data within the fragment identifier."
  3. we should add a test when_fragment is used as a path parameter name, e.g. /fragment/{_fragment} both for generating and matching. and a test with a same document relative reference with just a fragment, e.g. #fragment as a result.

@fabpot
Copy link
Member

fabpot commented Sep 14, 2015

@rodnaph Can you address @Tobion concerns?

@rodnaph rodnaph force-pushed the router-generate-document-fragment branch from 1847f98 to 049f0c6 Compare September 14, 2015 09:10
@rodnaph
Copy link
Contributor Author

rodnaph commented Sep 14, 2015

@Tobion

I've addressed your first two concerns.

For the third I thought the best solution would be to throw a LogicException when compiling the route, as _fragment has no meaning as a path parameter. I'm not sure what you meant about "a test with a same document relative reference with just a fragment" - would that be a route with no pattern? eg. new Route(''); ?

I also rebased onto current master as there were some failing lint issues.

/cc @fabpot

@bendavies
Copy link
Contributor

+1 @Tobion

@@ -59,6 +59,13 @@ public static function compile(Route $route)
$staticPrefix = $result['staticPrefix'];

$pathVariables = $result['variables'];

foreach ($pathVariables as $pathParam) {
if ('_fragment' == $pathParam) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be ===.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though not documented, it looks like the variables output by compilePattern will always be strings, so a strict type equality would not be required.

Unless of course this is a coding standard, or maybe if a test could show it was required (as it seems to me without proof either way then both strict and non-strict comparison have the possibility of causing a bug).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our coding standards are that we always use strict comparison unless we explicitly need the type juggling (because type juggling can actually cause totally unexpected behavior if you are not careful).
And given we know that strings are always returned, we know we don't need this type juggling.

@rodnaph rodnaph force-pushed the router-generate-document-fragment branch from c005615 to 31e1d21 Compare September 18, 2015 15:08
if ($extra && $query = http_build_query($extra, '', '&')) {
// "/" and "?" can be left decoded for better user experience, see
// http://tools.ietf.org/html/rfc3986#section-3.4
$url .= '?'.strtr($query, array('%2F' => '/'));
}

if ($fragment) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is broken for $fragment = '0'

@rodnaph rodnaph force-pushed the router-generate-document-fragment branch from 31e1d21 to 344291d Compare September 21, 2015 08:46
@rodnaph
Copy link
Contributor Author

rodnaph commented Sep 21, 2015

@inso Fixed, thanks.

@@ -59,6 +60,13 @@ public static function compile(Route $route)
$staticPrefix = $result['staticPrefix'];

$pathVariables = $result['variables'];

foreach ($pathVariables as $pathParam) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

array_search?

@rodnaph rodnaph force-pushed the router-generate-document-fragment branch from 344291d to 5f00a59 Compare October 22, 2015 13:53
$extra = array_diff_key($parameters, $variables, $defaults);

// extract fragment
$fragment = isset($extra['_fragment']) ? $extra['_fragment'] : false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default value should be "", not false

@fabpot
Copy link
Member

fabpot commented Mar 4, 2016

Apart from my small comment, 👍

ping @Tobion

@rodnaph Can you rebase on current master?

@rodnaph rodnaph force-pushed the router-generate-document-fragment branch from 5f00a59 to 342d7eb Compare March 4, 2016 12:01
@rodnaph
Copy link
Contributor Author

rodnaph commented Mar 4, 2016

@fabpot done

if ($extra && $query = http_build_query($extra, '', '&')) {
// "/" and "?" can be left decoded for better user experience, see
// http://tools.ietf.org/html/rfc3986#section-3.4
$url .= '?'.strtr($query, array('%2F' => '/'));
}

if (strlen($fragment)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be '' === $fragment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'' !== $fragment

@rodnaph rodnaph force-pushed the router-generate-document-fragment branch from 342d7eb to 6d79a56 Compare March 26, 2016 23:11
@fabpot
Copy link
Member

fabpot commented Jun 16, 2016

Thank you @rodnaph.

@fabpot fabpot merged commit 6d79a56 into symfony:master Jun 16, 2016
fabpot added a commit that referenced this pull request Jun 16, 2016
…ment (rodnaph)

This PR was merged into the 3.2-dev branch.

Discussion
----------

[Router] added appending of new optional document fragment

added a new optional parameter to the generate method for the document fragment. when specified this is appended to generated urls.

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | none
| License       | MIT
| Doc PR        | none

Commits
-------

6d79a56 [Routing] adds _fragment special option to url generation for document fragment
fabpot added a commit that referenced this pull request Jun 17, 2016
…ms (xabbuh)

This PR was merged into the 3.2-dev branch.

Discussion
----------

[Routing] treat fragment after resolving query string params

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

The implementation from #12979 led to a conflict with #18280 which was merged in the meantime.

Commits
-------

7475aa8 treat fragment after resolving query string params
@King2500
Copy link
Contributor

King2500 commented Jul 6, 2016

Why not use the more intuitive (and less conflicting) parameter key # instead of _fragment, like:

// generating a URL with a fragment (/settings#password)
$this->get('router')->generate('user_settings', ['#' => 'password']);

@Tobion
Copy link
Contributor

Tobion commented Jul 6, 2016

@King2500 true, could be an alternative. I guess _fragment was the first idea because it's also _locale that has a somewhat special meaning.

@javiereguiluz
Copy link
Member

@King2500 I'm always in favor of short option names, but in this case I'd prefer to keep the consistency. Every special routing option in Symfony follows the same pattern: _controller, _locale, _route, _route_params, _redirected, etc.

wouterj added a commit to symfony/symfony-docs that referenced this pull request Oct 6, 2016
…(alexislefebvre)

This PR was squashed before being merged into the master branch (closes #6783).

Discussion
----------

Routing: add explanation for the "_fragment" parameter

Add explanation about this PR: symfony/symfony#12979

Presented in http://symfony.com/blog/new-in-symfony-3-2-routing-improvements

I copy-pasted the start of the announcement as the explanation since I couldn't have found a better explanation. I hope that won't be a problem.

Commits
-------

d657abd Routing: add explanation for the "_fragment" parameter
@fabpot fabpot mentioned this pull request Oct 27, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.