Skip to content
Luke C Hartman edited this page Jul 29, 2024 · 17 revisions

NEW

Proxy Media Files from Production Site

To reduce the size of your local WordPress installation while still being able to access media files, you can configure your local Nginx server to proxy requests for media files to your production site.

Steps to Set Up Proxying

  1. Navigate to the Nginx Configuration Directory

    • Go to the root directory of your local WordPress installation.
    • Navigate to the /conf/nginx directory.
  2. Create a New Configuration File

    • Create a new file named uploads-proxy.conf in the /conf/nginx directory.
  3. Add Proxy Configuration

    • Paste the following content into the uploads-proxy.conf file, replacing https://www.mediaengagement.org/wp-content/uploads/ with the URL of your production site's uploads directory:
      location ~ ^/wp-content/uploads/(.*) {
          if (!-e $request_filename) {
              rewrite ^/wp-content/uploads/(.*) https://www.mediaengagement.org/wp-content/uploads/$1 redirect;
          }
      }
  4. Modify the Main Nginx Configuration File

    • Open the site.conf.hbs file in the /conf/nginx directory.
    • Locate the WordPress rules section:
      #
      # WordPress Rules
      #
      {{#unless site.multiSite}}
      include includes/wordpress-single.conf;
      {{else}}
      include includes/wordpress-multi.conf;
      {{/unless}}
    • Add the following lines after the WordPress rules section to include the uploads-proxy.conf file:
      #
      # Proxy requests to the upload directory to the production site
      #
      include uploads-proxy.conf;
  5. Save and Restart

    • Save the changes to the site.conf.hbs file.
    • Restart your local site using the Local by Flywheel control panel.
  6. Verify the Configuration

    • Load your local site in the browser to ensure that the images are now being loaded from the production site's uploads directory.

First Day on the Job

  1. Make sure you have logins for the WordPress site (mediaengagement.org), wpengine, and the appropriate permissions for the Github repository. You might have to talk to the lead developer and your manager to get this taken care of.

  2. Then visit the README and get your local environment set up. Using an IDE like Atom or Visual Studio Code makes life easier when it comes to version control and syntax checking, but this is all up to preference.

  3. Once the website is working properly on your machine, you're good to begin working. We have a system of tracking ongoing projects using Github issues that you'll use eventually. There will be some projects that don't require any code to be written as you'll be working solely in the admin panel of WordPress. When the time to code does come around, you'll need to follow the steps that we take to keep versioning sound so everyone can work independently. Please read the Wiki on Git Usage to get an understanding of how branching and taking on a project is handled.

  4. Finally, talk to the lead developer and your manager to figure out what would be the best project to get you familiar with WordPress and our code.

If you haven't worked with WordPress before, I encourage you to traverse the admin panel on your local site. Break some things, fix them, change some posts, do anything you think will help you gain familiarity. If something breaks on your local, you can always git reset --hard origin/master to get back to a working version at the cost of losing your changes. So create new branches and commit often.

When it comes to the code, you'll be working under the engage directory ~/Local Sites/mediaengagementorg/app/public/wp-content/themes/engage. It will take some time to get used to the structure and knowing where in the code you need to access for your project. To help get you going in the right direction, if the change you're making is to the front-end you'll want to look inside the templates folder and scss under assets. Backend logic and querying happen inside of PHP files, the src folder has a lot of it, but there are some lose PHP files out and about.

It might be a little overwhelming at first, but after a couple of weeks, things will begin to make sense. You'll be on your way to making big changes in no time. Don't hesitate to ask for help from each other if you get stuck. Welcome to the CME team!

Installation

the long version

  1. Download and install the WP Engine Local App.

    • The Local App is a WP Engine program that allows you to easily set up a WordPress environment on your local computer.

    • After download choose your platform
    • Fill in your information
    • Download and Save the installation package to your computer
    • Open the installation package for Local on your computer
    • Follow the installation setup prompts
    • Launch Local on your computer
  2. Enable wpe api and generate credentials

    • Open the API Access page of your WP Engine User Portal:
    • Locate the account name you wish to enable access for
    • Click Manage
    • Toggle Account API Access to on
    • Click Generate Credentials to return to the previous page
    • Click the Generate Credentials button at the top
    • Leave this page open for easy access in the next step
  3. Connect Local to WP Engine

    • Open the Local application on your computer
    • Click Connect at the top left
    • Click LOG IN TO YOUR HOST
    • Select WP Engine
    • Copy and paste your WPE API credentials, from the previous step
    • Click LOGIN TO WP ENGINE
  4. Pull to Local from WP Engine

    • This process needs to take place the very first time you pull to Local from WP Engine. ** If you are not added as a user on the remote WP install add your user profile via phpMyAdmin.
    • Ensure you’ve already connected Local to your WP Engine account
    • Open Local on your computer
    • Go the Connect tab
    • Locate a Site in the list
    • Click PULL TO LOCAL
    • Choose whether or not to include the database, if you include the database then you can skip steps 6 and 7
  5. (Optional) In wp-config.php: keep debug warnings from displaying on the front end

    define( 'WPE_CLUSTER_ID', '0' );
    define('WP_DEBUG', false);
    ini_set('display_errors','Off');
    ini_set('error_reporting', E_ALL );
    define('WP_DEBUG', false);
    define('WP_DEBUG_DISPLAY', false);
    

If you included the database in your PULL TO LOCAL then you can skip steps 6 and 7.

  1. (Optional) Download database from WP Engine
    • In WP Engine Portal visit cmengage from Sites tab
    • phpMyAdmin tab
    • In phpMyAdmin click wp_cmengage tab
    • Export top tab
    • Export method: select “Custom” bullet
    • Scroll to bottom of page and click Go
      • if timeout occurs on export select 50% of tables in “Tables:” and export, then select the final 50% and export.
  2. (Optional) Move database download to Local socket.
    • Upload the database file downloaded from phpMyAdmin in step 14.

      mysql -uroot -proot -h localhost --socket "/Users/[USERNAME]/Library/Application Support/Local/run/EzKVmKywD/mysql/mysqld.sock" local < /Users/[USERNAME]/Downloads/wp_cmengage.sql
      
      • [USERNAME] replace with your local computer username
      • /Users/[USERNAME]/Downloads/wp_cmengage.sql replace path to downloaded database file in step 14.
      • EzKVmKywD Local spins up a specific instance of mysql that's used only by that site - EzKVmKywD being a unique ID to the site you have. If you were on a production server, you'd normally just use mysql -uUSER -pPASSWORD to get connected.
        • To find this unique ID:
          1. cd /Users/[USERNAME]/Library/Application\ Support/Local/run/
          2. ls
        • The unique ID should be listed.
  3. Edit the wp_config file
    • Go to the line containing /** MySQL database password */
    • Ensure the password and username are 'root'. The host should be localhost
  4. Edit ~/Local Sites/mediaengagementorg/app/public/wp-content/enp-quiz-config.php
    • Comment out the following lines inside the else
      echo 'unknown quiz config path for '.$site;
      die;
      
    • This is a temporary fix for quiz-tool, if you end up working on quiz tool you will need to redo the pathing below the if structure.
  5. In the Local App under the Local Sites tab click View Site button to open
  6. Connecting/syncing with github
    • cd into ~/Local Sites/mediaengagementorg/app/public and enter the following commands
      git init
      git remote add origin https://github.com/engagingnewsproject/enp-platform.git
      
    • If you are re-adding the origin and get a Remote origin already exists error run:
      git remote set-url origin https://github.com/engagingnewsproject/enp-platform.git
      
    • And then fetch from origin:
      git fetch --all
      git reset --hard origin/master
      
    • At this point your directory should now be connected with our repo and up to date with master.
    • Small aside, if you need to update your database, pull from WPENGINE again and include the database.
  7. Browser refreshing (browsersync)
    • cd into ~/Local Sites/mediaengagementorg/app/public/wp-content/themes/engage
    • Enter the command npm install
    • Edit webpack.mix.js to make sure the browsersync proxy field is the url of your Local site host.
    • If you run into any issues (localhost:3000 opens to a blank screen), check your node version: node -v. At the time of writing, make sure you are using node v16.13.2. To manage node versions: NVM. ex nvm install 16.13.2 and nvm use 16.13.2.
    • To view live scss or css changes while developing run npm run watch. Ignore the errors for now if it's working.
    • When done developing, ^ + c, and minify for production npm run production.

Important Links

SSH commands

Connect to site (replace environment with site name.):

$ ssh -i ~/.ssh/wpengine_rsa -o IdentitiesOnly=yes [email protected]

Activate default WP theme: wp theme activate twentytwentyone --skip-themes

Get directory sizes:

$ du -h --max-depth 1

Coding and Workflow

Run the development server

See the npm commands section

Coding best practices

A collection of general tips and rules of thumb when coding and building a project.

Think about the performance impact of your code and solutions

For example:

  • will the change increase the weight of our page?
  • will the change increase our load time?

Don't include large files/libraries when you only need a small subset of it.

For example:

  • importing jQuery for one thing when the site doesn't need it otherwise
  • including the entire Font Awesome icon set when you only need 5 icons.
  • using Bootstrap. You likely don't need to use Bootstrap for one of our projects.

Simple is better than Clever

Clever can be fun, but always at the risk of complicating things and making life more difficult for your future self and others. Opt for unglamorous, simple code to save yourself a headache down the road.

If being clever is going to save you a lot of time or be a big performance boost, be sure to put it in a very simple, well-documented standalone function or module with a simple name that clearly explains what it does, why it should be done this way, and how it works.

Functions should do one thing

When writing a new function, make sure that it accomplishes one, specific thing. This keeps the code:

  • more testable,
  • easier to debug,
  • easier to read / understand,
  • easier to maintain

Some rules of thumb. You probably need to break apart your function into several smaller functions if:

  • if you have a really long function name
  • if your function code is many lines long or has many steps

If you can't figure something out, ask for help. But not before trying to solve it yourself first.

This advice isn't in order to stop you from asking questions, but because some of the best learning happens when you think hard about trying to figure it out on your own. Google it. Read an article or two. Chances are you'll learn something, even if it doesn't lead you to the exact thing you needed to know.

When asking questions, be sure to be detailed on:
  • what you're trying to solve
  • why you need to solve it
  • what you've already tried
Writing a good question does a few things:
  • helps you organize your thoughts
  • gives you a chance to think about the problem in a different way
  • often leads you to the correct answer

I'd estimate 30% of the time I've written a detailed question, I figure out the answer before I finish writing it or right after I ask it :)

Make sure your editor doesn't reformat on save, unless we have something like prettier implemented

When people have different format on save rules, it makes it really hard to review Pull Requests (PR). For example, if one person uses a two tab vs four spacing autoformat on save, the PR will show everyone of those lines from the file as a change rather than just the work that was completed. So, maybe you made one small change, but now every line in the file is shown as a change. This makes it difficult to identify the real change.

Get only the data you need

When writing a query or requesting data, it's best to get just what you need (or will likely need) rather than

Keep things organized

  • Look at the existing code base and see if it makes sense for code to be in one place or another. If it doesn't have an obvious place, create a new file using the existing standards of the code.

CSS

Don't use !important in your CSS unless you have a really, really good reason

That's it.

Keep specificity low.

CSS uses specificity to determine which rules get applied. The rule with the highest specificity will get used.

So:

  • body .classname p { color: red; } would win over p { color: blue; }

A few tips:

  • Don't use #ids, as those increase the specificity a lot
  • Use classnames or HTML elements to target things
  • Try to keep two levels deep at the most, like: .classname-one .classname-two {}.
  • Ideally keep things one level deep: .classname__item {}

Use BEM naming conventions

This helps keep specificity low and helps you organize your code. Google it to find out more. Here's the basics:

  1. .article is like the root element or block
  2. .article__title is the element underneath the block. Use __ to indicate this.
  3. .article--research or .article__title--red is the modifier of the element/block. Use -- to do this.
  4. Don't bother doing more than one element, even if it is technically built that way. For example, .article__title__link would technically be used for this structure <article><h1><a></a></h1></article>, but it's really annoying and doesn't benefit that much. Just give it a unique element name like .article__title-link.

CSS via SCSS

Engage CSS is compiled with SCSS.

  • When you start up your dev environment with npm run watch changes to SCSS files located in the assets/scss directory are compiled (via the assets/scss/app.scss file) to engage/dist/css/app.css.
  • When running npm run production at the end of your development session engage/dist/css/app.css is minified for the production environment.

SCSS Workflow

Since we use mobile first design the first properties you call on an element will be for the mobile display. The same with @supports at-rule.

This way you shouldn't really ever have to use @include media($mobile) mixin because you identify the mobile styles first. Just as will the fallback (flex) rules. So you wont have to use the not keyword in the @supports rules. They are simply the default :)

For example:

.archive__content {
  display; block;                    // for mobile we want the content to span the entire width so we set it to block.
  @include media($tablet) {
    display: grid;                   // for all screensizes larger than tablet we want a flex layout.
    flex-flow: row wrap;
    flex: 0 0 80%;                   // for tablets we want the sidebar to be next to the content so we allow it 20%.
  }
  @include media($laptop) {
    flex: 0 0 85%;                   // for desktop screens we want the content to allow 15% (a bit less) for the sidebar.
  }
  @supports (display: grid) {        // at the end of our rule we add out styles for browsers that support grid layout.
    grid-column: 1 / -1;
    @include media($tablet) {
      grid-column: 3 / -1;           // we can get real crafty and add the media query mixin inside of the @supports rule. 
  }
}

A simple breakdown:

  1. Styles for mobile and older browsers(aka fallback rules)
  2. Styles for larger screens
  3. @supports rules for supporting browsers. Within the @supports at-rules refer back to #1 (mobile first, then larger screens).

Mixins & Variables

As a general rule try to use the mixins and variables as much as you can. This will ensure design continuity and better code maintenance for future devs. A good example is the $spacer variable. If we always use this variable, or the other variants that apply ($spacer-sm, $spacer-md, $spacer-lg ext.) we can easily change them in one file. Same with mixins.

Mixins In Depth

Media Queries

See the assets/scss/global/_mixins.scss file.

For PHONES use:

@include media($mobile) {
  .home-section {
    margin: $spacer;
  }
}

this outputs:

@media (min-width: 400px) {
  .home-section {
    margin: 1.6rem;
  }
}

TIP: you should generally not have to use the $mobile mixin because we use mobile first design so the first properties you call on an element will be for the mobile display.

For PHABLETS use:

@include media($phablet) {
  .selector {
  }
}

outputs: @media (min-width: 600px) {}

For TABLETS use:

@include media($tablet) {
  .selector {
  }
}
  • outputs: @media (min-width: 800px) {}

For LAPTOPS use:

@include media($laptop) {
  .selector {
  }
}

outputs: @media (min-width: 1000px) {}

For DESKTOP use:

@include media($desktop) {
  .selector {
  }
}

outputs: @media (min-width: 1200px) {}

TIP: if you add 'max' before the device name your media query will output a 'max-width:' up to the number right below the 'min-width:' values above.

For example:

@include media('max', $desktop) {
  .selector {
  }
}

outputs:

@media (max-width: 1199px) {
  .selector {
  }
}

. . . and so on for the other media query mixins

@supports (display:grid){} -- Mozilla Documentation

Engage Structure

Timber & Twig

Engage is based on the Timber Framework using the Twig templating engine. Explore the links below to learn more.

Working on tasks

Read through our Issue Tracking and Git Usage wiki for details.

ACF How To

  1. Find your fields and repo template file.

    When working on an existing page the best way to find the fields associated with that page is to

    • visit the page,
    • edit the page,
    • open the custom fields in a new tab with the gear icon in the fields header:

Edit custom fields

You will then have access to the field names, which you can copy and search the repo code to find the associated template.

  1. Export/Import new fields

Once you are done on your local dev site, you will need to export your new ACF's for import on the Dev, Staging & Production site.

  1. On your local dev site WP Admin dashboard navigate to Custom Fields/Tools.
  2. Select your custom fields and click Export.
  3. Log in to the Dev site WP Admin dashboard and navigate to Custom Fields/Tools.
  4. Import the file you exported from your Local Dev site.
  5. Repeat steps 1-4 for the Staging and Production sites.

Notes on Post Type Archive Queries

Basically the whole site archive structure is powered by queries set in src/Managers/Permalinks.php. We've overridden the default queries so we can set our own queries with the verticals added in. There may be a better way to do this, but this way at least gets us a very specific way of modifying the query based on a pretty URL.

To adjust a query, you'll need to add/modify the query in src/Managers/Permalinks.php and then re-save the permalinks in Settings->Permalinks.