Establishing the Fully Managed Website Service Model
Author
ZayadurDate Published
Upper Echelon has been a prominent player in the online content space for years, consistently uploading informative YouTube videos. However, until recently, its website served little purpose beyond hosting these videos. Recognizing the need for a more user-friendly format, Upper Echelon launched the upperechelon.gg project. This initiative aims to enhance user experience by allowing viewers to digest video content at their own pace, while also leveraging web technologies to expand Upper Echelon's capabilities.
The Need for Improved Content Accessibility
With a wealth of information packed into each video, Upper Echelon identified a gap in how users interacted with this content. The new website, built on the WordPress platform, addresses this gap by providing a structured format that allows users to access and engage with video content more effectively. This project not only meets the immediate needs of users but also opens doors for innovative ideas and features in the future.
Implementing Dynamic Content with YouTube API
One of the first steps in this project was to create a dynamic way to pull in the latest YouTube videos using the Data v3 API. Hosted on a LEMP (Linux, Nginx, MySQL, PHP) stack, the team implemented several key strategies:
1. Secure Environment Variables: The project began by storing environment variables in the filesystem using one of three secure methods. This ensured that sensitive information remained protected.
2. Accessing Variables in PHP: The team accessed these variables within the php-fpm scope, integrating them into functions.php. This approach not only streamlined the process but also made these variables available for future development.
1[website.tld]2user = webmaster3group = www-data4listen = /var/run/php/php8.2-fpm-website.tld.sock5listen.owner = www-data6listen.group = www-data7php_admin_value[disable_functions] = exec,passthru,shell_exec,system8php_admin_flag[allow_url_fopen] = off910pm = dynamic11pm.max_children = 512pm.start_servers = 213pm.min_spare_servers = 114pm.max_spare_servers = 31516env[DB_NAME] = "database_name"17env[DB_USER] = "database_user"18env[DB_PASSWORD] = "database_password"19env[DB_HOST] = "database_host:port"20env[AUTH_KEY] = 'generate_unique_key_here'21env[SECURE_AUTH_KEY] = 'generate_unique_key_here'22env[LOGGED_IN_KEY] = 'generate_unique_key_here'23env[NONCE_KEY] = 'generate_unique_key_here'24env[AUTH_SALT] = 'generate_unique_key_here'25env[SECURE_AUTH_SALT] = 'generate_unique_key_here'26env[LOGGED_IN_SALT] = 'generate_unique_key_here'27env[NONCE_SALT] = 'generate_unique_key_here'28env[WP_DEBUG] = "false"29env[WP_ENVIRONMENT_TYPE] = "production"
3. Optimizing API Calls: To avoid unnecessary API calls that could lead to errors, the team utilized WordPress features like transients. This caching mechanism buffered API calls, ensuring efficient data retrieval without overloading the system.
1/* Get and cache the latest YouTube video ID using transients. */23// Fetches and caches the most recent video ID from a YouTube channel.4function get_latest_youtube_video_id($channel_id) {5 // Check cache first6 $cached_video_id = get_transient('latest_youtube_video_id');78 if (false !== $cached_video_id) {9 return $cached_video_id;10 }1112 // Get API key from environment.13 $api_key = getenv('YOUTUBE_API_KEY');14 if (!$api_key) {15 error_log('YouTube API Key not found in environment variables');16 return 'NVlDLVfhFL0'; // Fallback video ID17 }1819 // Make API request.20 $api_url = "https://www.googleapis.com/youtube/v3/search?key=$api_key&channelId=$channel_id&part=snippet,id&order=date&maxResults=1&type=video";2122 $response = wp_remote_get($api_url);23 if (is_wp_error($response)) {24 error_log('YouTube API Error: ' . $response->get_error_message());25 return 'NVlDLVfhFL0';26 }2728 // Process response and cache result.29 $data = json_decode(wp_remote_retrieve_body($response), true);30 $video_id = !empty($data['items'][0]['id']['videoId']) ? $data['items'][0]['id']['videoId'] : 'NVlDLVfhFL0';3132 set_transient('latest_youtube_video_id', $video_id, 86400); // Cache for 24 hours3334 return $video_id;35}3637// Generate Video Iframe HTML.38function get_latest_video_iframe() {39 $channel_id = 'UChI0q9a-ZcbZh7dAu_-J-hg';40 $video_id = get_latest_youtube_video_id($channel_id);4142 return sprintf(43 '<iframe width="560" height="315" src="https://www.youtube.com/embed/%s" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',44 esc_attr($video_id)45 );46}4748// Creates [latest_video] shortcode for use in posts/pages.49function latest_video_shortcode() {50 return get_latest_video_iframe();51}52add_shortcode('latest_video', 'latest_video_shortcode');53
YouTube Data API v3 error metrics before and after buffering API calls via WordPress transients.
Enhancing Error Tracking with Sentry
Another significant enhancement involved creating a Sentry plugin to collect and send logs to a Sentry account. This project arose from the realization that the WordPress ecosystem lacked a simple, low-overhead Sentry plugin. The available options were either overly complex or required payment, which felt unjustified. By developing this plugin, Upper Echelon provided a straightforward solution for error tracking, improving the overall reliability of the website.
1// Initialize Sentry using the DSN from environment variables2$dsn = getenv('SENTRY_DSN');3if ($dsn) {4 Sentry\init(['dsn' => $dsn]);56 // Set error handler to capture unhandled exceptions7 set_error_handler(function ($severity, $message, $file, $line) {8 if (!(error_reporting() & $severity)) {9 // This error code is not included in error_reporting10 return false;11 }12 Sentry\captureException(new ErrorException($message, 0, $severity, $file, $line));13 return true;14 });1516 // Register shutdown function to catch fatal errors17 register_shutdown_function(function () {18 $lastError = error_get_last();19 if ($lastError && ($lastError['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR))) {20 Sentry\captureException(new ErrorException(21 $lastError['message'],22 0,23 $lastError['type'],24 $lastError['file'],25 $lastError['line']26 ));27 }28 });29}
Offloading Media with WordPress Spaces
As each article on the new site would feature thumbnails from corresponding videos, the team faced the challenge of managing server space effectively. To address this, they initiated the WordPress Spaces project, which allows for reliable media offloading. This solution ensures that server storage is optimized while still providing users with access to essential media files. More details about this project can be found at WordPress Spaces.
Modernizing WordPress Development Practices
To bring WordPress development up to modern standards, Upper Echelon implemented several key practices:
1.Repository Initialization: A Git repository was initialized in the web root of each website, mirroring the /var/www/{domain} location on the VPS. This setup allows for a streamlined workflow, with the repository reflecting the production branch.
2.Robust .gitignore: The team created a comprehensive .gitignore file to track only the wp-content/plugins and wp-content/themes/child-theme folders. This focus ensures that the bulk of custom functionality is deployed efficiently while keeping the repository clean and manageable.
1# Common2*.log3*.sql4*.sqlite5.DS_Store6Thumbs.db78# Artifacts9*.tmp10*.bak11*.swp12*.zip13*.tar.gz1415# Project16.env1718# Composer19vendor20composer.*2122# Core23/*24!.gitignore25!wp-content/2627# Content28wp-content/*29!wp-content/plugins/30!wp-content/themes/31!wp-content/mu-plugins/3233# Plugins34wp-content/plugins/*35!wp-content/plugins/sentry/36!wp-content/plugins/sentry/sentry.php3738# Themes39wp-content/themes/*40!wp-content/themes/salient-child/
3.Deploy Key Setup: A Deploy key was generated for each repository, enabling the webmaster:www-data user to push and pull changes after authenticating with the Deploy key via an SSH agent. This setup enhances security and simplifies the deployment process.
4.Local Development and Automated Deployment: Developers can now code PHP and update styles locally from any environment. Once changes are ready, they can push updates to the repository. A script then takes over to pull the latest changes, or a GitHub Action can be configured to automatically trigger a pull on every pushed or merged update into the production branch. This automation streamlines the deployment process and reduces the risk of errors.
What's Next?
The launch of the upperechelon.gg project marks a significant step forward for Upper Echelon. By enhancing content accessibility, improving error tracking, and optimizing media management, the team is well-positioned to provide a richer user experience. As they continue to explore new web technologies, Upper Echelon is set to expand its capabilities and further engage its audience.
Optimize your WordPress site with the WordPress Spaces plugin, offloading media to DigitalOcean Spaces for efficient management and synchronization.