History.pushState(data,title,url) concatenates (instead of replacing) url to address bar if there is a trailing slash - history.js

For example,
If I use the search bar from "www.site.com" I see "www.site.com/search", which is fine.
If I use the search bar from "www.site.com/events/" I see "www.site.com/events/search", which is silly.
Why does it do this? Is this the behavior or a history.js bug or my bug?

Give an example of what you are doing.
If your current URL in the address bar has the form: http://somesite.com/path/
And you pass pushState( null, null, 'newpath' ); in this case, the link will look like http://somesite.com/path/newpath but if you pass a parameter as: pushState( null, null, '/newpath' ), in this case would look like this:
http://somesite.com/newpath

If your application is not deployed at the root (such as with a virtual directory, or just in a deeper hierarchy) then you'll end up screwing up the URL if you do history.pushState({}, '/newpath');
There's a couple alternatives :
1) Get your root path in a javascript variable that you can just prepend the URL to it. In this example window.ViewModel.rootPath is just an arbitrary place - just modify this for however you want to store global variables.
You will have to set the rootPath in script (example here for .NET).
<script>
window.ViewModel.rootPath = "#Request.ApplicationPath";
</script>
history.pushState({}, window.ViewModel.rootPath + '/newpath');
2) Check if the URL ends with a / and if it does you need to go up 1 directory level. Note: This approach requires you to know the 'parent' directory of what you're posting - in this case YourAccount.
history.pushState({ mode: 'Club' }, '',
(window.location.href.endsWith('/') ? '../' : '') +
'YourAccount/ManageClub/' + id );
If the current URL is /preview/store/YourAccount then this will become ../YourAccount/ManageClub/123.
If the current URL is /preview/store/YourAccount/ then this will become YourAccount/ManageClub/123.
These with both end up at the same URL.

Related

DNN rewriting URL and adding Default.aspx? in Query-String

I have a Product list page on DNN.
On this module I have a function which is called when clicked. I am adding the name of the product and SKU in the URL as a Querystring. I noticed that DNN would rewrite ?Title= to /Title/ as well as &SKU= to /SKU/ when the SKU is normal without a forward slash. For example SKU/SR2018B
The URL below would work:
www.ourwebsite.com/Product-View/Title/staple-remover-black/sku/SR2018B
My main problem is when the SKU has a special character like a forward slash, for example: SS023/10. This will cause the URL to break. I am using an encoder for the SKU. Notice that ?Title did not change to /Title/ and now there is a Default.aspx? present in the URL below.
www.ourwebsite.com/Product-View?Title/staples-2313-1000pcs-100-pages/Default.aspx?sku=SS023%2f13
Here is my Code Behind when a person is redirected to the Detailed Page.
if (tabIdToRedirectTo == null) m_alerts.ShowModuleMessage(ModuleMessage.ModuleMessageType.RedError, $"An error occurred when attempting to Redirect to the '{settingKey}' Page!", ref plcMessages, true); else Response.Redirect(Globals.NavigateURL(tabIdToRedirectTo.TabID, "", "?Title="+ hiddendescription.Value + "&sku=" + HttpUtility.UrlEncode(hiddensku.Value), EmbeddedModule.GenerateFullQueryStringForEmbedding(EmbeddedCompanyCode, EmbeddedShowCustPricing)));
I believe it's how you're calling the Globals.NavigateUrl function. The call takes a params of strings which are your query strings in the key=value format. I usually like to easily see what I am about to pass so I do something like the following:
var qsParams = new List<string>{
"Title=" + hiddendescription.Value, // "Title=staples-2313-1000pcs-100-pages"
"sku=" + HttpUtility.UrlEncode(hiddensku.Value), // "sku=SS023%2f13"
EmbeddedModule.GenerateFullQueryStringForEmbedding(EmbeddedCompanyCode, EmbeddedShowCustPricing)
};
return Globals.NavigateURL(tabIdToRedirectTo.TabID, "", qsParams.ToArray());
Granted - I do not know what your EmbeddedModule.GenerateFullQueryStringForEmbedding does, but as long as it returns a key=value type output, it should be passed and processed well.

Is there a way to assign an external URL to a HyperLink without appending http:// or https:// (ie, the protocol)?

I have a HyperLink defined like so:
<asp:HyperLink ID="hltest" runat="server"></asp:HyperLink>
In my code, I do this:
hltest.NavigateUrl = "www.google.com"
However, the actual link looks like this:
http://localhost:53305/www.google.com
I can append http:// to the URL, but this not the preferred method because this URL is maintainable by the user. If the user saves the URL as http://www.google.com then the URL will end up looking like http://http://www.google.com. I know that I can strip http:// from the URL and then add it back to ensure that it doesn't show up twice, but this is extra code/helper method that I would like to avoid writing.
Edit: This is the type of code I am trying to avoid having to write:
hltest.NavigateUrl = "http://" & "hTTp://www.google.com".ToLower().Replace("http://", String.Empty)
Update I know I specifically asked how to do this without appending the protocol to the URL, but it looks like there's just no other way to do it. The selected answer brought me to this solution:
Function GetExternalUrl(Url As String) As String
Return If(New Uri(Url, UriKind.RelativeOrAbsolute).IsAbsoluteUri, Url, "http://" & Url)
End Function
This is great because, if the user enters just www.google.com, it will append http:// to the URL. If the user provides the protocol (http, https, ftp, etc), it will preserve it.
Use the Uri class and handle it accordingly:
Uri uri = new Uri( userProvidedUri, UriKind.RelativeOrAbsolute );
if( !uri.IsAbsolute ) hltest.NavigateUrl = "http://" + userProvidedUri;
else hltest.NavigateUrl = userProvidedUri;

Query strip is removed from open graph url

In relation to this question: Dynamic generation of Facebook Open Graph meta tags
I have followed these instructions but the api seems to remove my query string so that the url passed into the aggregation contains none of my dynamic information. If I enter the url with the query string into the debugger it doesn't remove it and works fine. I can confirm my og:url meta tag does also contain the same query string not just the base url. What am I doing wrong?
I was having a similar issue and solved it like this:
So assuming you're doing your post request like it shows in the tutorial, youre Javascript probably looks something like this:
function postNewAction()
{
passString = '&object=http://yoursite.com/appnamespace/object.php';
FB.api('/me/APP_NAMESPACE:ACTION' + passString,'post',
function(response) {
if (!response || response.error) {
alert(response.error.message);
}
else {
alert('Post was successful! Action ID: ' + response.id);
}
}
);
}
And since you say you want to generate meta tags dynamically, you're probably adding a parameter to the url (passString) there like so:
passString = '&object=http://yoursite.com/appnamespace/object.php?user=' + someuser;
This is wrong.
What you need to do is to make the url a 'pretty url' and use htaccess to decipher it. So:
passString = '&object=http://yoursite.com/appnamespace/object/someuser';
Then your htaccess file will tell your site that that url actually equates to
http://yoursite.com/appnamespace/object/object.php?user=someuser
Then you can use GET to store the user parameter with php and insert it however you like into your meta tags.
In case youre wondering, in the og:url meta tag's content will be:
$url = 'http://yoursite.com/appnamespace/object/object.php?user=' . $_GET[$user];
Does that help?

ASP.NET MVC Routing for files with muliple sub-directories

I need to setup a file handler to route with multiple sub directories something like tihs;
http://localhost/images/7/99/786936215595.jpg
I tried putting this in the global.asax file;
routes.Add(
"ImageRoute",
new Route("covers/{filepath}/{filename}",
new ImageRouteHandler()));
I am using the ImageHandler found in this Question, which works great if you have a single sub-directory (ie '/images/15/786936215595.jpg') but fails when you have multiple directories.
I tried setting up a wildcard and that didnt work (ie 'new Route("covers/{filepath}/*/{filename}"')
This is serving images from a large NAS (think something like 3 million images) so its not like I can just move files around.
Thanks!
Ok after much playing around and google fu I found how to make it work.
Change the route definition like this;
routes.Add(
"ImageRoute",
new Route("images/{*filepath}",
new ImageRouteHandler()));
Then put this after the default MapRoute. The important part is the "*" before the filepath, tells MVC to send anything following this as part of the filepath RouteData. So in the GetHttpHandler() method I can get the full path by using this;
string fp = requestContext.RouteData.Values["filepath"] as string;
Woot!
Can't you treat the entire path as one route parameter? Like so:
routes.Add(
"ImageRoute",
"/images/{path}",
new { controller = "Image", action = "Image" }
);
And then access the entire path in the ActionResult Image(string path) { } action method?

drupal path alias exist or not

How to find whether url is exist or not ? i.e url that leads to 'page not found' error . for ex: finding test/testpage is exist or not
i mean that to check whether given relative path or full path is really exist on the site or it leads to page not found error
You can use the menu_valid_path() function for this. This returns TRUE or FALSE based on 1. Whether the menu path exists and 2. if the current user has permission to view the item.
You call it like this:
$item_exists = menu_valid_path(array('link_path' => $some_path));
Where $some_path is the path you want to test.
If you want to know does only an alias exist or not, use:
$path_exist = drupal_lookup_path('alias',$path);
But if you want to know does one of system path or alias is exist, use:
$path_exist = drupal_lookup_path('alias',$path) || drupal_lookup_path('source',$path);
Since Drupal 8.8, Path Alias is a content entity.
So we can use
$pathStorage = \Drupal::entityTypeManager()->getStorage('path_alias');
$aliases = $pathStorage->loadByProperties(['alias' => $alias]);
// or
// $pathStorage->loadByProperties(['path' => $path]);
$existingAlias = count($aliases) > 0;
Refer to this URL for Drupal 8.
You can use:
\Drupal::service('path.alias_storage')->aliasExists('current_path', 'en')
And it will load "1" if alias exists in system.
Also you can use requesting page: http://api.drupal.org/api/function/drupal_http_request/6
On error you will get not empty $result->error.
For Drupal 9 \Drupal::service('path.alias_storage')->aliasExists() is not longer available.
But you can use:
$path_alias_repository = \Drupal::service('path_alias.repository');
if ($path_alias_repository->lookupByAlias($alias, 'en')) {
return TRUE;
}
Solution is taken from here.

Resources