Problem/Motivation
I'm starting to move some of my simplest webforms to D8 and I've noticed another feature that seems missing in contact + contact storage. I think it would be great if contact forms were able to have their own custom URL aliases like other types of content in the system.
Currently you can add an alias in the system manually. However if you have a lot of forms the ability to use pathauto patterns would be helpful and/or the ability to create the alias individually on the form itself (without the /contact in front of the form label).
Proposed resolution
Add a new URL alias field to the contact form edit page which allows creating a new alias automatically on insert/update (via the normal url_alias
functionality in core)
Remaining tasks
Patch
Tests
Review
User interface changes
New field for alias
API changes
None
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#31 | url_alias_support-2743657-31.patch | 6.98 KB | Bambell |
|
Comments
Comment #2
jwillard CreditAttribution: jwillard commentedComment #3
larowlanUpdated OP
Comment #4
toncic CreditAttribution: toncic at MD Systems GmbH commentedI added a new URL alias field to the contact form and test coverage for it.
Comment #5
toncic CreditAttribution: toncic at MD Systems GmbH commentedComment #7
toncic CreditAttribution: toncic at MD Systems GmbH commentedI rerun the test locally and it works...not sure what testbot needs to make this to work.
Comment #8
andypostSuppose here should be a language!
hasValue() makes sense first!
compare with "/" only once
Comment #9
BerdirThe test fails are likely due to a change in 8.2.x. Update to the latest versio and it will fail like that for you as well. Open a separate issue about fixing that.
There is no third party setting for this. You need to get the default value from the alias storage instead.
unrelated change.
do not save something in a validate function. Maybe some other validate function fails then and then the form is not submitted.
Instead, do the save in the form builder above for example. (but keep the validation here)
$filename is also a weird variable name. In the form builder, you have $contact_form, then you can just do $contact_form->toUrl()->getInternalPath() and just have to prepend /.
Comment #10
toncic CreditAttribution: toncic at MD Systems GmbH commentedI thinks is not need it. Do you have example?
When I'm using 'hasValue()' for empty it returns me true.
Comment #12
andypostsuppose you need to check
isEmpty()
s/$filename/$id or $entity_id
Comment #13
zerolab CreditAttribution: zerolab at Torchbox commentedA few code style nitpicks. See https://www.drupal.org/coding-standards/ for reference. It helps running code sniffer (https://www.drupal.org/node/1419988)
URl -> URL
nitpick: space after
,
space around
.
Comment #14
toncic CreditAttribution: toncic at MD Systems GmbH commentedI removed the function "contact_storage_form_contact_form_validate", because in "contact_storage_contact_form_form_builder" I need that check and is point less to have again the same condition.
Comment #16
toncic CreditAttribution: toncic at MD Systems GmbH commentedCreated followup #2778937: Fix contact storage test.
Comment #17
Berdirno longer needed.
and this as well.
Two things here:
a) you still need the validate function. this will just silently do nothing if it is not valid, that's bad for user experience. Instead, you want to display a validation error if a value is set and is not correct. You should also test for that.
b) I was wrong about the builder function. this called too early, we need a submit callback (additionally to the save callback) that stores it.
as I said above, try saving with an invalid value. And also add an assert on the contact form title or so additionally to the drupalGet() and an assertResponse(). the drupalGet() will not fail if this is a 404.
Comment #18
toncic CreditAttribution: toncic at MD Systems GmbH commentedAdded callback functions for validation and submit. Test coverage.
Comment #20
toncic CreditAttribution: toncic at MD Systems GmbH commentedI created an issue #2780763: Add missing parameter in ContactFormCloneForm::__construct() to fix this test failed.
Comment #21
Bambell CreditAttribution: Bambell at MD Systems GmbH commentedGood work overall. Here are some points to improve :
Can we remove this old commented code?
That's not exactly the correct way to document a function's parameters :
Please add a space after commas.
Please add a space after if's.
Functions have to be documented.
Missing space after if.
Code that test functions need to execute before doing actual work normally lives in the
setUp()
function. Please move the user creation and login code there. This function doesn't need to be explicitly called.Comments should be formatted as proper sentences, so it should end with a dot.
We don't really want to write unit tests here. A single function covering all test cases of the URL alias functionality would be more appropriate. Also, it would be more straightforward to assert for the contact form's label than the page title. We are doing this only to make sure we land on the correct page. We also want to assert that :
Comment #22
toncic CreditAttribution: toncic at MD Systems GmbH commentedFixed coding standard, put everything in one function and added new test cases.
Comment #24
Berdir$this is not $form_data, use $alias or so.
Also, you now also check this if the entity is new, that doesn't make sense, there can't be an alias yet, there is no id yet. And you can access this much easier through $contact_form.
if (!$contact_form->isNew()) {
if ($alias = ...->load('/' . $contact_form->toUrl()->getInternal()) {
// set #default_value here.
}
}
two spaces indendation for description.
same here, get the entity with $form_state->getFormObject()->getEntity(), then use the same method as above.
You should also implement this more like \Drupal\path\Plugin\Field\FieldType\PathItem::postSave()
Try to load first, only delete if you find something and there is no new alias, if there still is an alias, save it, but pass in the pid.
This is important so that automatic redirects work, for example, from the old to the new alias.
Comment #25
toncic CreditAttribution: toncic at MD Systems GmbH commentedFixed coding standards and change login in submit callback function.
Comment #27
Berdiryou can remove this now.
you updated all other calls but not yet this one.
Comment #28
toncic CreditAttribution: toncic at MD Systems GmbH commentedRemoved old comment and using $entity->toUrl()->getInternalPath().
Comment #29
BerdirI think the order of arguments needs to change here now.
test the invalid path first and make sure that the page then *does not* exist yet. This order is a bit weird.
I'm not sure what this is testing exactly. you're not checking if it is empty, you're explicitly setting an empty path.
I don't think this is very useful. What you wnat to check instead is that for example editing a page with an alias correctly shows that default value, and re-saving it does then still work.
And, beside removing the alias from a form, we also want to test that deleting a form also deletes the alias in the database, so we don't leave left-overs there.
Comment #30
toncic CreditAttribution: toncic at MD Systems GmbH commentedI created new feature branch, because there was some commit and there are to much merge conflicts. I implement new function to delete alias when we deleting a form. Also change some test case.
Comment #31
Bambell CreditAttribution: Bambell at MD Systems GmbH commentedLooks good to me. I made some various improvements, most notably in the test function. Please have a look at the interdiff @tonic92.
Comment #32
BerdirNice clean-up. test coverage looks just like I imagined it now :)
Comment #33
andypostI just wondered why not reuse
\Drupal\Core\Render\Element\Url
Comment #34
BerdirGood point, lets use #type url, that should validate automatically.
Comment #35
Bambell CreditAttribution: Bambell at MD Systems GmbH commentedI'm not too sure. 'url' form element apparently expects absolute url's. See
Drupal\Core\Render\Element\Url::validateUrl
and thenDrupal\Component\Utility\UrlHelper::isValid
. We want to be able to create aliases for relative url's.Comment #36
BerdirConfirmed, you are right. #type url supports only external URLs.
Comment #37
andypost@Berdir strange because core's LinkWidget using it to point local routes
Comment #38
BerdirNo, it actually doesn't, it changes the #type to entity_autocomplete if internal urls are allowed: https://api.drupal.org/api/drupal/core%21modules%21link%21src%21Plugin%2...
Comment #39
larowlanthanks!
Comment #41
ckaotikThis issue is not quite fixed because the current implementation does not work with non-English systems. The alias should be created in the correct language (whichever that may be).
Currently, on a German-only system the alias gets created as language 'en', which Drupal does not know and therefore the alias does not work. Furthermore, it seems to have messed with the previously existing (identical) German alias.
Comment #42
BerdirYes, the hardcoded en there is wrong, I missed that. Can you open a new issue, though? Re-opening issues quickly gets confusing.
Make sure you include something like this:
Decide if we should use the config entity language or LanguageInterface::LANGCODE_NOT_SPECIFIED. We can't support creating translated aliases properly from the form anyway.
Comment #43
ckaotikThis issue had not been closed, so I didn't technically re-open it ;) In my eyes, fixing the hard coded language is part of this issue (the current implementation breaks url aliases entered on /admin/config/search/path), but whatever. Feel free to open a new issue.
Comment #44
Ginovski CreditAttribution: Ginovski at MD Systems GmbH commentedOpened issue about the hardcoded language:
https://www.drupal.org/node/2796335