logo

Implementing DXL Inject® – "The Cuckoo Pattern" - PHP Deployment

In my series of Implementing DXL Inject ®, the next post will explore how Crownpeak FirstSpirit can deploy a PHP payload to a web server that runs the php-fpm module.

Like with previous posts, we’ll use the SmartLiving Reference project provided by Crownpeak in my forked repository - https://github.com/ptylr/smartliving-website.

Test Harness Modifications

The only modifications I've made to the test harness are to deploy a Docker Container that has both nginx & PHP v8.3 installed and configured and then share volumes and networks. I've mapped host TCP8081 to TCP80 on the web server.

Diagram of docker-compose.yml

#         __          .__
# _______/  |_ ___.__.|  |_______
# \____ \   __<   |  ||  |\_  __ \
# |  |_> >  |  \___  ||  |_|  | \/
# |   __/|__|  / ____||____/__|
# |__|         \/
#
# https://ptylr.com
# https://www.linkedin.com/in/ptylr/
#
##########################################################################
services:
    firstspirit:
        hostname: firstspirit
        container_name: firstspirit
        build:
            context: ./firstspirit
            args:
                IMAGE_VERSION: ${IMAGE_VERSION}
        image: crownpeak/firstspirit-dev-env:${IMAGE_VERSION}
        environment:
            IMPORT_DEMO_PROJECTS: ${IMPORT_DEMO_PROJECTS}
        ports:
            - "8000:8000"
        volumes:
            - firstspirit-conf:/opt/firstspirit5/conf
            - firstspirit-data:/opt/firstspirit5/data
            - firstspirit-delivery:/var/www
        networks:
            - firstspirit-local-dev-environment
    delivery-nginx:
        hostname: delivery-nginx
        container_name: delivery-nginx
        build:
            context: ./delivery-nginx
        image: crownpeak/firstspirit-dev-env-delivery-nginx
        ports:
            - "8080:80"
        volumes:
            - firstspirit-delivery:/var/www
        networks:
            - firstspirit-local-dev-environment
    delivery-nginx-php:
        hostname: delivery-nginx-php
        container_name: delivery-nginx-php
        build:
            context: ./delivery-nginx-php
        image: crownpeak/firstspirit-dev-env-delivery-nginx-php
        ports:
            - "8081:80"
        volumes:
            - firstspirit-delivery:/var/www
        networks:
            - firstspirit-local-dev-environment
networks:
    firstspirit-local-dev-environment:
        driver: bridge
volumes:
    firstspirit-conf:
    firstspirit-data:
    firstspirit-delivery:

FirstSpirit Server Configuration

First, let's "Change Properties" on the SmartLiving Website Reference project and add a new "Template Set". FirstSpirit Server Manager FirstSpirit Template Sets

Create a new "Template Set" named "php", set the "Presentation Channel" to "HTML", use the "Convert HTML" conversion rule and set "php" as the target file extension. Select "Yes" to use the new Template Set for all project schedules. FirstSpirit Edit Template Sets FirstSpirit Generate Template Set

We must create a "Full Deployment" schedule for the PHP Template Set. However, by default, it will be added to the existing schedule used for static HTML deployment, so we need to modify that configuration before adding one for our new Template Set. FirstSpirit Edit Template Set

Update the "Schedule Entry Name" of the existing "Full Deployment" entry to "Full Deployment (Static HTML)". FirstSpirit Update Schedule Entry Name

Amend the "generate" Action to remove "php" from the list of Template Sets to use for generation - this will leave only the "html" Template Set. FirstSpirit Amend Generate Action

Create a new Schedule Entry using the "Copy Schedule Entry" option. Copy the existing "Full Deployment (Static HTML)" entry. FirstSpirit New Schedule Entry

Rename the copied Schedule Entry to "Full Deployment (PHP)". FirstSpirit Rename Schedule Entry

Edit its "generate" Action to select only the "php" Template Set (de-selecting the "html" option). FirstSpirit Edit Generate Action

Rename the "Deploy (Static)" Schedule Entry to "Deploy (PHP)" and change the deployment path to "/var/www/php" (which corresponds to the shared volume with the nginx+php-fpm Docker Container). FirstSpirit Rename Deploy Static

Finally, update the "generate" action to reflect TCP 8081 under "Prefix for absolute paths", as configured on the docker-compose.yml. FirstSpirit Update Generate Action

FirstSpirit Template Configuration

FirstSpirit allows each Template Set to work independently, allowing completely different experiences to be delivered from the same piece of content. However, as I only want to prove my ability to deliver PHP from FirstSpirit, I will make as few modifications as possible by re-using the existing HTML Template Set and minor modifications to show the PHP deployment capabilities.

Upon entering FirstSpirit's SiteArchitect, I see that the new (PHP) Template Set is available for all Template Types. However, as I want to use the HTML Template Set for most functions, I will include the following lines of code in each PHP Page Template. The CMS_SET function will give me a variable I can use in Section Templates.

$CMS_SET(st_serverside_language, "PHP")$
$CMS_RENDER(#this, templateSet:"html", pinTemplateSet:true)$

The only other change I will make is to amend the Teaser Section HTML Template to use the variable we set earlier to render a PHP tag for execution server-side.

$CMS_IF(st_serverside_language != null)$
<?php echo "<p class='mb-5 text-coolGray-500 font-medium'><b>[This text is generated by $CMS_VALUE(st_serverside_language)$ using a server-side control. It is not visible in CMS edit/preview mode.]</b></p>" ?>
$CMS_END_IF$

FirstSpirit Site Architect

That's it. Now, just execute the deployment of the Schedule Entry for "Full Deployment (PHP)" and browse to http://localhost:8081/homepage/homepage.php to see the PHP version of the site. Note the server-side generated text on the Homepage. Final Result

Conclusion

Deploying PHP from FirstSpirit is as simple as configuring a server target, creating a new Template Set for parallel publication and declaring how that Template Set should behave during output generation.

Although we've covered a simple PHP script delivery as part of this post, the power exists to deliver content using any technology or framework to execute as server-side capabilities – this enables you to deliver much more complex application scenarios natively from FirstSpirit.

Stay tuned for further posts on Crownpeak's DXL Inject® pattern, where I'll show you how other technologies and languages from FirstSpirit can be deployed quickly to support every digital touchpoint.