How to insert hyperlinking anchors throughout an OJS 3.1.2 site (system links inclusive)?

Anchor-linking to div IDs doesn’t work on paths. For example, when trying to insert a link anchor in the path of an added Navigation Menu Item (via Settings-Website), this error is returned refusing to accept the # sign: " Errors occurred processing this form [The path field must contain only alphanumeric characters plus ‘.’, ‘/’, ‘-’, and ‘_’.]/management/settings/website#path)"

Not to mention that system links don’t allow you to edit their path anyway (they’re not even displayed, let alone faded so they couldn’t be edited).

Any ideas how to append #my-anchor-something to all internal links at once, or at least to some? I think this should be a straightforward thing to do, like in HTML5. But instead, it’s turned into a nightmare.

The path restriction on the custom navigation menu item appears here:

What is your specific use-case with wanting to add an anchor to all internal links?

Thanks. So will simply inserting the “#” sign anywhere in the highlighted part do the trick for all the internal links as well, not just those that the system allows editing the path of?

Anchor links aren’t that uncommon though, so why protect the OJS from the # character in the first place?

Edit Adding a # to the highlighted string made no difference (regardless of the position of the #-sign within the highlighted string). Path edits with a # are still forbidden, so there must exist another lock somewhere.

An anchor can be appended to a URL when there’s full access to the HTML source, but that’s a limited number of situations - for example adding block with the Custom Block Manager. But the situation with static pages and Navigation menus is absolute disaster, everything feels like locked behind seven locks. I don’t understand, what’s the possible harm of a #?

I confirmed that adding the ‘#’ character into that regexp will allow it in the UI, but now I’m not as certain that it should be allowed.

This input is essentially creating a URI handler for a new page on the system. The fragment marker, while valid in a URL, does not really belong in the handler. Fragments aren’t passed to the server for processing, they are handled client side.

I’m still unclear what your objective is with re-routing “all links” to a specific fragment marker. Can you help me understand your use case?

That’s interesting @ ctgraham, in theory at least. However, we need a practical solution for what shouldn’t have been a problem in the first place. I’ve never heard of a platform actually preventing users from using anchors.

So generally speaking (regardless of our specific needs), you can help only by explaining what you meant by “I confirmed that adding the ‘#’ character into that regexp will allow it in the UI” - add what/where, exatcly?

In the existing regex, the # mark must be placed in the [] character classing, and can be placed anywhere not adjacent to a hyphen (or the backslash). For example, I tested:

if (!preg_match('/^[#a-zA-Z0-9\/._-]+$/', $this->getData('path'))) {

I now tried that exact position @ ctgraham. Still can’t save a static page with an anchor in the path. Although the error.log recorded no errors., a little red error tag appears underneath the path field:
OJSerrorSavingAnchor

On inspec, the little tag belongs to .pkp_form label.error and sub_label error classes.

I’m also interested to find out about these three issues:

  • where does OJS3 generate the internal links in the nav bar, so that we can edit them manually (append “#-my-anchor”) to them?

  • for some reason, the usual .htaccess redirect to a custom 404 page doesn’t work (probably due to restful_urls = On), so OJS3 returns its own 404 page with a “404 not Found” message instead. Where is this little text string generated, so that we can at least edit this string into a message that says something more user-friendly?

  • what is the class of that ugly background on site-wide alerts/popups: #d00a6c ? Inspec didn’t return any meaningful class.

1 Like

This doesn’t appear to be a Navigation Menu Item entry. That would start out with the Title and then the NMI type, then the Path:
image

I suspect you are editing a Static Page, rather than a Navigation Menu Item. In 3.x, the Navigation Menu Item is preferred to old Static Page plugin, but the Static Page plugin will still work. The code for the Static Page plugin is here:

1 Like

I think the classing on the notification popups with #d00a6c is:

.notifyError .ui-pnotify-text,
.notifyFormError .ui-pnotify-text,
.notifyWarning .ui-pnotify-text,
.notifyForbidden .ui-pnotify-text {
 background:#d00a6c
}

The OJS 404 handler is here:

There is a fair amount of abstraction in the link generation. If you are only concerned with the links in the navbar, it might be possible to simply modify the NavigationMenuItem::getPath() method to return the path suffixed with your fragment.

Yes of course @ ctgraham, a Static Page so the paths of Static Pages can’t be appended a “#”. Thanks for the plugin path, however, I was able to append a # to the path of the Navigation Menu Added items. It works without editing any files including those two files that you mentioned: PKPNavigationMenuItemsForm.inc.php#L209 and StaticPageForm.inc.php#L46. Maybe it works because OJS3 asks for entire URL for an Added Item, but only the path/slug for a Static Page? That seems the only interesting difference, in the backend at least.

But unlike for Static Pages (won’t take anchors) or for Navigation Menu added items (will take anchors), OJS3 doesn’t make the paths of Navigation Menu internal items/links available in the backend for display or editing. Appending #nav-menu to those links via your file NavigationMenuItem.inc.php#L60 didn’t work either (I tried all variants for concatenating two strings I could think of). Even the removal of that entire line has affected no internal items/links in the Navigation Menu, so those default links still generate normally. That made me think if I am in the right location: /lib/pkp/classes/navigationMenu/NavigationMenuItem.inc.php ? (But then, removing of that file crashes the site so this seems like the right location after all.)

I found a simple solution to the OJS force-redirect from missing files/folders to the OJS generic 404 message when restful_urls = On in config.inc.php (instead of redirecting to a custom 404 page), so that the expected .htaccess redirect doesn’t happen even when a custom 404 page is present. Instead of trying to make the string on line 252 of your file Dispatcher.inc.php#L247-L253 more user-friendly and stylish, just replace the line 251

header('HTTP/1.0 404 Not Found');

with

header('Location: /404.html');

where 404.html is your custom 404 page (here in the OJS root). The extensions can be .htm, .html, ,shtml, .php.

While reading the PKP forum I noticed somewhere that this 404 issue has been raised in the past, but was marked low priority. However, given how simple it is to resolve, you may wish to implement it in an upcoming update, or as a specs comment at least.

Your class(es) for changing the site-wide alert’s background color from #d00a6c to something else, didn’t work - not even with the !important flag after clearing all the caches (browser’s as well as all three OJS’s) and re-logging, see the Submissions deletion alert for example - the color still pervades in both background and button text styles:

OJS3_AlertBackgroundColor

2 Likes

The “Delete submission?” prompt styling is coming from:
.pkpListPanelItem__mask.-alert

1 Like

Hi @ ctgraham, unfortunately that class didn’t work/change the color.

What specifically was your css statement, and how did you load it?

Be aware that the Custom CSS file as specified in Settings → Website → Appearance only affects the public site.

Well, you found the problem then, as I was trying only with that file. So how do we style the backend then?

See:
https://docs.pkp.sfu.ca/pkp-theming-guide/en/theme-backend

1 Like

That’s too advanced for most users. It’s too bad the backend isn’t at least a little bit (color-) customizable and in an as easy way as the frontend is customizable entirely. Such a radical difference really took me by surprise.

Both the added stylesheet for the backend and the custom 404 redirect would be suitable to file a Feature Requests within GitHub issues:

That will give them attention for possible scheduling in a future release.

And what about revealing the path of all internal links so they could be freely appended anchors to? I mean, if paths of Navigation Menu’s added items/links and of all links in all Custom Blocks are already available and thus can be anchored, then there’s no reason why the paths across the rest of the internal linking structure (Static Pages and the Navigation Menu’s internal items/links) wouldn’t be made such as well, is there? It sounds like a ready-made solution here too, just waiting to be simply transplanted.

I still don’t have a good picture of what use-case there is for globally adding a fragment marker to all URLs across the navigation, so I can’t recommend adding that as a feature request.

If I were approaching something like that, I think what I might do, rather than modifying the PHP code to output URLs with the fragments, would be to add a javascript snippet to add the fragments where you want them on page load. This could readily be accomplished with the Custom Header plugin: