Score:-1

Best way of entering an internal link

ng flag

How can I enter an internal link that works for different path lengths and keeps working when I upload my site to the live server?

Say I have a page here http://localhost/site1/web/page1 and I want to create a block in the footer that has a link to this page.

If I use a relative link (e.g. page1) It will work when I'm on this page ...
http://localhost/site1/web/
But it won't if I'm on a multi segment path, e.g ...
http://localhost/site1/web/about/terms/

If I create a server-relative link (e.g. /site1/web/page1)
It will not work when the server changes ...
http://mysite.com/
(I develop the site locally on my PC and when the site is finished I upload it to my hosting site).
Also, it will not work if I wish to clone the site...
http://localhost/site2/web/

Absolute paths (e.g.http://localhost/site1/web/page1)
will also not work when I start running the site on the live server.

I tried the module linkit. It works for the above cases but only for some types of links (e.g. I couldn't get it to work for links to views).

Module pathologic fixed this issue in Drupal 7 but is not yet ready for Drupal 9.

I got the best results using the php module (it supplies a filter that you can add to a text-format). But I believe using this module is frowned upon.

<?php
use Drupal\Core\Link;
use Drupal\Core\Url;
print(Url::fromUserInput('/node/1')->toString());
?> 

Am I missing a better alternative? (It would be handy if there was a way to make links that are relative to the drupal 'web' directory.)

Jaypan avatar
de flag
Blocks are content entities, not configuration entities, and therefore usually are not migrated between instances, making this a moot point for most systems, since the block must be created separately on each instance, allowing the path to be set for that specific instance. If you are migrating your blocks between your local environments and remote environments, how are you doing this?
Kevin avatar
in flag
Use a menu block? What's wrong with menu links? I've never had an issue linking in a WYSIWYG like this either.
Jaypan avatar
de flag
It might not be a menu.
ng flag
@Jaypan I dont want to make modifications directly on the live site, but instead develop the site on my local PC and when I've fixed all the bugs etc, I copy the files across to the remote server and import the database. So I just need to change the database details in settings.php. So the blocks get migrated over along with the rest of the drupal. Also, the needs of my various customers are usually quite similar, so I often can reuse a drupal site. Hence the need to clone.
apaderno avatar
us flag
Did you try the *Custom Menu Links* module that comes with Drupal core?
ng flag
@apaderno Yes. I use that module. My question is more about links in general. I might have a footer block where it contain links to internal pages (e.g. T&Cs), copyright statement, telephone numbers. So menu block is not ideal.
Kevin avatar
in flag
Why aren't you entering the relative path? "/some/alias"?
ng flag
@kevin "/some/alias" would take me to "http://localhost/some/alias". But I need to go to "http://localhost/site1/some/alias/". I.e. I have several sites on the same server when I'm developing.
Kevin avatar
in flag
Relative path is independent of the domain.
ng flag
@kevin this is a relative path (no leading slash): "some/alias" and it is independent of the domain but doesnt work if the number of segments in the path changes.
cn flag
Both are relative paths. Without slash is relative to current path, with slash is relative to domain root. What you’re trying to do is serve multiple sites from subfolders in a single domain, and yeah, that can get awkward for manual linking. I don’t believe there’s a universal solution, but in my experience if you can solve it in web server config with rewrites, it’s often easier to do it there than trying to get Drupal to augment every link in the site
ng flag
Thanks @Clive. Maybe I'm not developing sites the correct way. Out of interest, how do you develop sites? Do you work directly on the live site, or do you just have one site running locally so you can have e.g. `http://localhost/page1` locally and then `http://mysite.com/page1` on the live server? Or do you do something else?
cn flag
My world's a bit different I guess; the nature of the sites I build means all content is managed by clients, and my job is to make sure the architecture/deployment supports that happening without ever needing to move content around (overwriting the production database is a last resort because the site could well be collecting data while development is happening). If there's a new feature, it's created in code, test content is created in a stage/uat environment and signed off, then the feature is pushed live and the real-world content is created in prod. For local dev I tend to prefer Lando
Score:1
de flag

In Drupal 8+, migrating databases is not recommended, as it will overwrite any changes made on your production server in between overwrites. Instead, a configuration API has been created, allowing for site configuration - aka the settings that define what a site is, what it does, and how it works - to be migrated by between instances without having to overwrite the database. There is also a Migration API, but in my experience it's usually easier to re-create content on production after first playing with it in staging/local than it is to set up the Migration API.

Here is a tutorial I wrote on using the Configuration API: https://www.morpht.com/blog/drupal-8-configuration-part-1-configuration-api

If I were in your position, I would stop pushing databases up, and instead switch to using the Configuration API to manage your site in multiple environments. Then you can create your block on production, and pull the database down to your local installation to get that block instance on your local installation.

If you don't want to switch to migrating configuration, and would prefer to keep pushing your database up, then the two solutions I see are:

  1. Use the PHP filter you mentioned in your post.
  2. Create a custom block through code, rather than through the admin UI, and build your link with the URL class as you showed in your most.

While the first option is not recommended, neither is the whole process of pushing the database up, so if you are going with pushing the database up then you many as well use the PHP input filter as well.

ng flag
Thanks @Jaypan. I will have a read of that. I dont have console access on most of my customers' shared hosting cPanel accounts (I can only upload files, use phpmyadmin and change a few settings). I'm guessing 'Configuration API' might not be possible here? I just do web design as a hobby and make sites for small organisations, so having the sites offline for a short period, while I update them, is not really a problem.
Jaypan avatar
de flag
You can still use the Configuration API.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.