Ticket #13705 (closed PLIP: fixed)
Remove BASE tag from rendered html
Reported by: | frapell | Owned by: | frapell |
---|---|---|---|
Priority: | minor | Milestone: | 5.0 |
Component: | Templates/CSS | Version: | |
Keywords: | Cc: | frisi |
Description (last modified by frapell) (diff)
Proposer: Franco Pellegrini
Seconder: Alan Runyan
Advisor: Balazs Ree
Motivation
- It is not easy (or even possible) to use HashBang routing inside of a JS application using a modern JS framework (angular, ember, marionette)
- Enable 3rd party Plone add-ons to ship JS MVC applications which extend Plone functionality
- Side effect of this will fix other issues
- Without a modern Javascript story; Plone is not as attractive.
Proposal & Implementation
- What and Why BASE href
- hysterical raisins, Zope -> CMF -> Plone
- ZMI uses BASE heavily
- hysterical raisins, Zope -> CMF -> Plone
- base indicates context in which relative URLs will take place
- Marshalling Arguments From Request from ZopeBook
- Allows you to have a <form action=”.”> <input name=”:method”>
- Remove BASE
- request.Response.setBase(None) in main_template
- ZPublisher/HTTPResponse.py actually scans to see if there is a base and if there is NOT one it will INJECT one into the outgoing HTML.
- Identified problems after removing BASE
- form_tabbing.js
- the original code uses a regexp to create a css selector for jquery if there is a / in the hashtag the css selector will be syntactically broken jquery stops there with a js expression. This is semi-fixed should be reviewed.
- https://github.com/reebalazs/plone_fb_messaging/blob/master/plone_fb_comcentral/skins/fb_comcentral/form_tabbing.js#L160-L167
- form_tabbing.js
- Inline validation
- inline_validation.js breaks. you can check, in line 30 of this file, there’s a POST using base’s href to generate the URL. On an edit template, base, has the current url without the final ‘/edit’. replacing “$('base').attr('href')” in this line with “location.href”, causes every field to return error (The red border around the field).
Today’s BASE href usage
NOTE: You do not have to think about JS. Out-of-the-box Plone/TinyMCE can demonstrate this problem.
- Add TinyMCE Anchor Link
- On new Plone, Edit Homepage
- Select text then click “link”
- TinyMCE Dialog select Anchors
- Select “Make it your own”
- Click Ok and Save Homepage
- New anchor HTML will be <a class="anchor-link" href="#make-it-your-own" target="_self" title="">Text which was selected to be linked</a>
- Go back to root of Plone, /, click Logo
- Look at your URL
- Now click the newly created anchor “Text which was selected to be linked”
- Now look at your URL (you probably saw page reload)
So lets say you had a JS application loaded on each of your pages:
- Presume invoking a JS application function by clicking a A tag. <a href=”#notes”> which will invoke it
- Presume editing default Plone homepage
- URL: http://host/front-page/edit
- BASE href: http://host/front-page
- clicking on #notes will reload your browser to a new context
- This behavior in various places already with Plone where by clicking on anchor tags will issue request.
Today’s Plone reliance on base tag
- Unclear how deep Plone is relying on BASE tag
- Need broader testing
Deliverables
- Fixes to inline validation, form_tabbing.js
- Browser view which setBase(None)
- make sure no JS uses $(‘base’).attr(‘href’)
- provide documentation on the base tag no longer being set so dependant JS doesn’t use it anymore and can use an alternative like $(‘body’).data(‘context_url’)
Risks
- BASE tag is used in Plone and will need to be fixed
- Third party Plone components using BASE tag and Form Marshalling
- Anything dependent on being relative
Change History
comment:1 Changed 3 years ago by frapell
- Owner set to vangheem
- Component changed from Unknown to Templates/CSS
- Type changed from Bug to PLIP
- Description modified (diff)
- Milestone changed from 4.x to 5.0
comment:3 Changed 3 years ago by garbas
i think you missed important aspect why base is the way it is now: SEO. (please correct me if i'm wrong)
while i agree we need a better javascript story i think javascript doesn't have to do anything with base element.
it was already proposed in the past (sorry cant remember in which pull request) to add data-* attributes to body element. in this case it would be "data-contexturl=...". i also played with this idea in plone.app.widgets, but dropped it because it required Chameleon and i want to be compatible with 4.3 for p.a.widgets package. now with 5.0 we'll be using Chameleon by default which makes data-* possible.
just to explain why data-* are possible with Chameleon. with pagetemplate you cannot pass a dictionary of attributes but with chameleon you can: tal-attributes="python:{'data-contexturl': '...'}"
that way you can create extendable configuration which can be also used from diazo. if we add data attributes and not remove base we would also keep reduce the risk of breaking code that require it.
comment:4 follow-up: ↓ 5 Changed 3 years ago by runyaga
Historical usage of BASE:
BASE exists because of Zope/CMF legacy. It was used so you could "self posting" forms. And sometimes you dont know (if you are on a container) where you should POST. For instance something like:
<form action=".">
<submit name=":method:aMethodOnContext" value="Do a call">
</form>
This use case as well as "how do you know where you are if you are on a default published method of a folder or a index_html page". This logic is old, crusty and needs to move forward.
Two things:
- Please provide evidence that BASE is related to SEO. I have not yet seen BASE on a SEO report.
- Also please review the TinyMCE / Anchor usage (described in PLIP) as it exists in Plone today.
Do you feel this is acceptable? Let's not think about javascript (although that is what brought us to this PLIP) for the time being.
I believe putting contexturl in the DOM is good idea. But that is separate from removal of BASE, correct?
Regarding Chameleon:
- I asked Steele to ship Chameleon with Plone; just with environment variable which disabled chameleon. There is no reason for chameleon *not* to ship with Plone 4.3.x (but disabled)
comment:5 in reply to: ↑ 4 Changed 3 years ago by garbas
Replying to runyaga:
- Please provide evidence that BASE is related to SEO. I have not yet seen BASE on a SEO report.
i'm not that that SEO savy person and would just like somebody with better understanding of SEO things to look at this as well before we decide to remove it. i might be completely wrong about base<->seo relation and i'll be very happy to get rid of base tag..
- Also please review the TinyMCE / Anchor usage (described in PLIP) as it exists in Plone today. Do you feel this is acceptable? Let's not think about javascript (although that is what brought us to this PLIP) for the time being.
we're all aware of the sorry state of tinymce integration in plone. hopefully p.a.widgets will make this easier.
I believe putting contexturl in the DOM is good idea. But that is separate from removal of BASE, correct?
well if we remove this information from the DOM then we need to add it somewhere (as data-* attribute) so it can be reused. and while doing it it would be nice to also add other information as well (roles, groups, ...). should this happen in one or two PLIP I dont really care.
Regarding Chameleon:
- I asked Steele to ship Chameleon with Plone; just with environment variable which disabled chameleon. There is no reason for chameleon *not* to ship with Plone 4.3.x (but disabled)
aware of that, but had different goals with p.a.widgets at the time.
also all of the javascript is almost rewritten in mockup (and tested to some extend, plip #13476). it would make sense to fix javascript there (and write tests for removal of base as well).
comment:6 Changed 3 years ago by runyaga
Rok,
I apologize I have be unable to get on #irc to talk at length. What I am referring to in TinyMCE is not "the sad state". I am talking about the use case I am bringing up. It has nothing to do w/ TinyMCE. If a user were to hand craft "sensible" HTML they would still have the same problem.
Are we in "violent" agreement? You want BASE to move to a dom attribute and get out of <head>?
A google search for my for "base tag seo" the first hit is::
Learn why you shouldn't use the tag. Article providing resources, tips and tricks that you can apply to improve your search engine rankings.
By "Pit stop media" - which I would not quote as an authoritative source. I am quite sure, in fact would bet real $, that BASE tag does not help nor hurt SEO. It is just a way of computing relative URLs.
If BASE has nothing to do w/ SEO. What are the arguments of keeping it. Since it causes issues with #anchors and in our specific case Angular (and probably all other JS frameworks).
comment:7 Changed 3 years ago by garbas
oh maybe i should state more clearly. here is a second try :)
I'm totally +100 on ripping base tag out, BUT before we do this i just want some SEO guru to look at this just so we don't make some stupid mistake. and clearly I'm not the that SEO guru, I just have in back of my head that base tag and SEO have some correlation. But I can be also totally wrong.
what i would also like to see is that there is "a way" to add more data-* attributes, like its already proposed for "data-context_url".
comment:8 Changed 3 years ago by davisagli
I'm worried about this change breaking content that uses relative links.
Currently on folderish items Plone sets a base that is the item's absolute_url() + '/', so relative links will start as children of the folder. On other items the base is just absolute_url(), so relative links will start as siblings of the item. So I'm worried that when viewing the default view of a folder, relative links will no longer resolve to the same absolute url.
Much as I'd like to get rid of our use of base, I don't think I can support a proposal along these lines unless it plans some migration to deal with that.
comment:9 follow-up: ↓ 10 Changed 3 years ago by runyaga
DG:"I'm worried about this change breaking content that uses relative links." AR: It should not break content that uses relative links. relative links *should* still work. Removing BASE href means relative links will work however a normal browser would interpret them without a explicit base tag. Plone 5 would move to absolute url computation for any links.
NOTE: In the scenario described in this PLIP BASE and #anchor tags are not working correctly. Can we agree that *today* we have broken behavior?
DG: Currently on folderish items Plone sets a base that is the item's absolute_url() + '/', so relative links will start as children of the folder. On other items the base is just absolute_url(), so relative links will start as siblings of the item. So I'm worried that when viewing the default view of a folder, relative links will no longer resolve to the same absolute url.
AR: Right but nothing used relative links. And this is the big question "Who is using relative links? and why are we not using resolveuid for links calculation, by default?" I looked through Plone and I could not see a case where relative links *are* being used. I think the idea would be to say "we have enough stuff to support; we are no longer supporting relative links."
NOTE: You can disable base now - put request.setBase(None) in mian_template - nothing in Plone breaks. So while I understand "the default view; relative links can break" - I say horse hockey to relative links - Acquisition will essentially make things work *groan* but no one should use relative links until Acquisition goes away. You should check your Z2.log sometimes - amazing what relative links can do to Spiders.
DG: Much as I'd like to get rid of our use of base, I don't think I can support a proposal along these lines unless it plans some migration to deal with that.
AR: "Deal with what"? Can you give me an example. What about writing a script which would convert all relative links to resolveuid which then can be transformed into absolute urls. I can sign up for that.
comment:10 in reply to: ↑ 9 Changed 3 years ago by davisagli
Replying to runyaga:
AR: "Deal with what"? Can you give me an example. What about writing a script which would convert all relative links to resolveuid which then can be transformed into absolute urls. I can sign up for that.
I'm pretty sure Plone still stores relative links if you don't have resolveuid-based links turned on. Even if that's not the case, there are legacy sites out there which have relative urls, and content which has been imported via custom scripts that has relative urls. We can't just break that content. So yes, I think that script to update links in existing content would be a necessary part of this plip.
comment:11 Changed 3 years ago by frisi
- Cc frisi added
just another usecase that demonstrates that anchors don't work as expected: https://github.com/smcmahon/Products.PloneFormGen/issues/90
comment:12 Changed 2 years ago by frapell
This PLIP has been implemented, and waiting for review.
https://github.com/plone/buildout.coredev/blob/5.0/plips/plip13705-remove-base-tag.cfg
Jenkins job with test passing 100%: http://jenkins.plone.org/view/PLIPS/job/plip-base-tag-removal/
comment:13 Changed 2 years ago by davisagli
I reviewed the branches; it's looking good.
You should also remove the 'renderBase' method in plone.app.layout and on the @@plone view in CMFPlone.
I don't think we need to worry about the change in how relative links resolve that I had brought up before; we've already been making all links absolute in the resolveuid transform for a while, and so it's up to that to resolve relative links in content correctly, rather than the browser using the base tag.
+1 for merging.
comment:14 Changed 2 years ago by frapell
- Status changed from new to closed
- Resolution set to fixed
comment:15 Changed 2 years ago by vangheem
This change has broken a basic use-case--linking an image to the home page of a plone site. If the site isn't behind virtual host monster, the image won't be linked properly. The same will happen with links on a home page.
Basically, the problem is that "localhost:8080/mysite" might have a link like "resolveduid/23849238432"
Without a base tag, this will cause it to be resolved to "localhost:8080/resolveduid/23849238432" which of course breaks because the plone site isn't in the url.
comment:16 Changed 2 years ago by vangheem
On second thought, perhaps this is a broken transform?
FWIW, I'm using coredev 5 latest.
comment:17 Changed 2 years ago by vangheem
Anyone mind if I remove the use of IResolveUidsEnabler in plone.outputfilters.filters.resolveuid_and_caption.
Since the removal of Products.TinyMCE, we are no longer doing that transform since the transform was registered there.
We should always be transforming now shouldn't we?