I have a number of related Devpack components that both use portal to add PHP code at the pageStart. They are dependant on their associated initialisation component.
It seems that the portal insertion code always adds at the page start regardless as to whether other portal pageStart code has already been inserted at the page start.
Ideally, the portal processing should insert the code in the order that it is requested on the page i.e. the first component to request it should insert right at the top and then the second component requesting should have its code inserted after the first one.
For the moment (and in this case) I can get round the problem by moving the first (initialisation) component after the second one.
I would like to be able to specify to a user using this DevPack that the initialisation component must be the first one on the page.
Are you saying that you have multiple separate components that rely on the presence of a âinitialisationâ component (and possibly each other)?
If so, we would like to remove any need for components having to rely on each other being on the page - (we donât want to end up with any components on the page that are for âconfigurationâ or setup code)
We actually have a way for developers to add initialisation / config / shared code. In your dev pack you can add the following shared file:
One thing to note is that pageStart and pageEnd are not currently supported in here, but I will discuss this with the team and see if itâs possible to get that added in the near future.
I think if the dev pack shared folder supported the pageStart, it might solve the issue youâre having, and hopefully remove the need for any type of initialisation/config components.
If you still think there would be a need for your initialisation component, please let me know the use case so I can better understand what youâre trying to achieve, and see if we can solve that in another way!
I have had a look at shared files but I would need to have page level user configurable properties which is why I am using an initialisation component. The user (web page designer) configures the Sitelok options when setting up the page.
The properties are used to setup the configuration for Sitelok and also to set user options so that when viewing in Preview the webpage can show either a logged in state or logged out state. The user needs to be able to flip this state easily amongst others. An example set of properties (work in progress):
I am aiming to make the setup of Sitelok as simple as possible and avoid the user having to copy and paste code into the Page Start section in the page settings.
There are other Sitelok components on the page: On or more Sitelok Control(s) and Sitelok Menu. Sitelok Control contains one or two drop zones: one for logged out and one for logged in. Sitelok Menu shows a different menu when logged in and logged out. Both of these need to know the logged in state to display correctly in Preview.
I hope I may have found a way round the Page Start ordering.
I want to find the best way to make this work with Elements.
An idea might be to have global properties (keyed by an id of some sort) that could be referenced in a component (a global properties section) that could be shared between components on a page. This means that the initialisation properties could be defined within the using components and changing a global property in one, would change it in the other. This would negate the need for an initialisation component?
Okay, I think for the time being continue doing what youâre doing to get things working. In a future beta weâll add a way to handle this much better - weâre thinking something along the lines of if you add one of the page lock sub components, Elements would automatically add a âSite configurationâ component for you.
However, if youâre doing any PHP setup/config type stuff then you will likely find the new Backend directory helpful
Files added to the backend directory are processed in the same context as other template files. However, instead of forming part of the page, they will be deployed as extra files to the pageâs backend directory during publish.
I am already using the â@portalâ feature. If I have multiple components inserting PHP code into the Page Start portal and I want a particular Component to have itâs PHP code first, the only way that can be achieved at the moment is to have that Component last on the page, as It seems that @portal(pageStart) always inserts at the start of the pageStart area.
Hi @ben, you can forget this request as I have worked out how to get round the issue.
Basically, include a Component that sets PHP $GLOBALS component configuration variables in a function and sets another $GLOBALS PHP variable to indicate whether the function has executed.
In all components that need the configuration data, check the $GLOBALS variable to see if the function has been executed and if not call it. It only needs to be called once for a webpage.
The function is embedded into the PHP code using @include which means that Elements properties used to set up the PHP configuration $GLOBALS variables are resolved and the configuration can be set in the UI Properties.
So this means it doesnât matter where in the page the configuration component is loaded. Setting this Component as an Elements global ensures that all pages use the same configuration data.
I have successfully tested this concept out with by my in-development Blog Devpack and will be able to apply it to the Sitelok Devpack when I get back to working on that.
Thanks for the great support from you and the team!
I am going to reopen this issue as I am now experiencing it across Components from different developer DevPacks.
There definitely needs to be a way to set the ordering of PHP code include in the PageStart @portal.
I am using a sitelok DevPack by @vibralogix and in another of my DevPacks (navigation menu) I am checking a PHP variable ($slpublicaccess) created by Sitelok which indicates whether the user is logged in or not.
If the Sitelok code in the PageStart @portal appears after my navigation code in the PageStart @portal, then the variable isnât found by my code because it hasnât been setup yet.
I want a way for the Sitelok code to be at the start of the Page ,so that is appears before my code. I have tried flipping the order of the components on the page, sometimes that works and sometimes it doesnât.
It would be helpful to add another field to the @portal with something like priority or order to set the code. This could then be taken into account when Elements builds the page.
Whilst I managed to get round the issue for components in my DevPack, I canât (at the moment?) for Components from different DevPacks.
I think this could be an ongoing issue as further developments take place using PHP?
We donât currently support ordering of @portal directives â and to be honest, I think it would be quite tricky to do reliably, especially when you have multiple components from different developers all wanting to be âfirstâ. It quickly becomes unclear whose code should take priority.
In cases like this, I think itâs better to approach the problem differently.
For example, in the CMS components, I often check for the existence of a function before including any required file:
@portal(pageStart, includeOnce: true)
if (!function_exists('my_function')) {
require_once '/path/to/my_function.php';
}
@endportal
Are you relying on code from one DevPack inside another entirely separate DevPack? That sounds like it could easily lead to brittle or broken setups
So far Iâve managed to build a complete set of CMS components and even an entire blogging system that integrated with a third-party service (even though we never ended up previewing it!) â and I havenât run into this issue myself.
Not trying to sound dismissive â but before we consider changing the core behavior, weâd really need a concrete example of a situation where you canât achieve what youâre trying to do in the current system. Happy to help troubleshoot or explore alternative solutions if you want to share more specifics!
I am using the Sitelok DevPack from @vibralogix which provides an Elements wrapper to the Sitelok PHP code.
This Sitelok DevPack controls membership login to the site and sets a PHP variable to indicate whether the user is logged in or not.
I have created a navigation DevPack that displays different content in the navigation bar depending whether the user is logged in or not. It does this by checking the value of the Sitelok PHP variable.
Both my DevPack and the Sitelok Devpack put PHP code are in the PageStart. If my DevPack code is inserted before the Sitelok DevPack code then the Sitelok PHP variable hasnât been setup at that point I need it and so my code fails. Obviously, I could check for it being missing but that doesnât help as I need its value to determine whether to show a logged out or logged in navigation bar.
I can definitely see why youâre running into issues â but Iâd still question whether itâs really necessary to check for the $loggedIn variable specifically in pageStart.
Itâs totally fair that both DevPacks might need to include something at the top of the page (like shared functions or initial setup), but from what youâve described, it sounds like the login check itself â especially if itâs just for conditionally showing navigation elements â could be done elsewhere in the layout.
That sounds like the key detail â why does the Navigation DevPack need to check $loggedIn in pageStart? Could it instead perform that check âinlineâ in the navigation component itself? Thatâs how Iâve handled this in the CMS components â using logic in the component where the output is actually needed, rather than assuming the result has to be available at the very top of the page.
If youâre still stuck and thereâs a technical reason it must happen early, feel free to post the relevant code (or even a GitHub repo) and Iâd be happy to take a look â Iâm pretty confident this can be made to work within the current structure.
I like my PHP initialisation code to be at the start of the document, not at the start of the HTML body statement. Itâs what is recommended by ChatGPT amongst others ,when I checked using the query: âIs there a downside of having PHP code that might normally be at the start of the HTML document but instead, include it just after the HTML body statement?â.
I think it would take too much effort to rework all my initialisation PHP code which is a lot more involved than just checking whether the user is logged in or not.
If I was doing my own code (without using Elements; heresy, I know ), I would simply order the code so that it worked as I intended.
Anyway, thanks for the offer of help but I donât want you to waste any of your time on this as I think I can work around the issue. Due to the open design and flexibility of Elements, I can achieve this by publishing as is and then lift the generated Sitelok Initialisation PHP code in the published index.php file and go back into Elements and insert it into the pageâs Extra Code area in the Page Start section (as a one off exercise). This gets output in front of the {{page.componentPageStart}} code which the Components fill with the @portal statements AFAICS? Then I will publish again and all should be well. The fact that the code will run twice doesnât matter. This achieves the objective of getting the Sitelok Initialisation right at the start of the document.
Going forward, I do think there is a case for being able to force PHP code right to the top of the document; especially for something like Sitelok from @vibralogix.
Indeed, if you were hand-coding outside of a drag-and-drop WYSIWYG editor, youâd probably structure the output a bit differently in some cases.
But thatâs the trade-off when building something designed to âjust workâ across a wide range of use cases â especially when considering compatibility with third-party components. Itâs all about striking the right balance between flexibility and ease of use