emory-libraries / templating-engine

A PHP templating engine for powering a dynamic website
0 stars 0 forks source link

Reconfigure the router for proposed server structure #16

Closed laurenhamel closed 5 years ago

laurenhamel commented 5 years ago

The router, including template loaders and data loaders, will need to be reconfigured for the proposed server structure.

To Do

laurenhamel commented 5 years ago

Part of this will be creating a hierarchy of routing data and figuring out how things get loaded.

  1. We’ll need to setup the router to use the requested URL and/or endpoint to determine (a) the appropriate environment to be used (i.e., production, staging, qa, dev, etc.), (b) the correct site's data to be used, and (c) the exact data file to be used. In the event that no data file exists, we should force a 404 and/or check for a redirect.

  2. We’ll need to extract and somehow merge any existing router data that we may have stored in a router.json file. We’ll also need to determine whether or not this predefined router data should overwrite or take precedence over any URL/endpoint data that we previously retrieved whenever the data differs. This may also overlap with the next bullet point.

  3. We’ll need check for dynamic endpoints and reconsider how we’re using and loading then. For instance, if we expect or want a data folder of employee bios to be loaded dynamically, the router will somehow need to recognize that each of those endpoints are dynamic and be able to identify the appropriate data source (re: folder) and data file to use.

  4. We’ll need to check for redirections. We can assume that any redirect data may be contained either directly in the endpoint’s data file or possibly in a separate redirects.json or similar data file. When we encounter a redirect, through, we’ll have to rethink and reconfigure the templating engine to more efficiently start this entire process over again.

  5. Once we hit a valid endpoint, meaning a data file was found, we’ll need to extract the template information from the data file in order to identify which template needs to be loaded. This may require some translation between template names/IDs as extracted from data files and template names/IDs as exported from the pattern library.

laurenhamel commented 5 years ago

@kristianserrano, I tacked on 2 bullet points to the list of to-dos above regarding dynamic routes/endpoints. We may or may not also want to break these out into separate issues to make sure we resolve how dynamic routes will be handled within the CMS. Also, if we create issues for setting up dynamic routes in the CMS, we may also want to go ahead and setup something similar for redirects.

kristianserrano commented 5 years ago

@laurenhamel sounds good.

  1. For determining domains, I was wondering about an environment config JSON file that stores paths based on domains. The engine identifies the host domain on which the request is coming in andrefers to that config for knowing which template and which data files to grab. a. Example: dev.libraries.emory.edu uses: -- dev template files -- staging content files b. Example: staging.libraries.emory.edu uses: -- prod template files -- staging content files c. Example: libraries.emory.edu uses: -- prod template files -- prod content files

  2. I don't anticipate storing any routing information in the CMS unless you think we need to. Let's discuss further though in case I'm misunderstanding.

  3. In the case of the employee profiles, for example, I wonder if the logic of loading the content dynamically would be in the template file itself for that specific content type or URL . Perhaps the template file can call a method that grabs all of the files (or an index of them) and loop through an object of that data.

  4. For redirects, I'm wondering if that's best left to the server before it hits the engine. We might be able to make the .htaccess editable from within Cascade even so that content people can manage the new URLs when things get moved. (More on that if we want to talk about it in person.)

  5. Logic in a high-level templating file (possibly a universal one), might be able to conditionally match types with templates. Not sure if there's a smoother way. Alternatively, I'm thinking about how Craft matches looks at an entry type slug ID and just calls a template file of the same name. We could have a hidden field in Cascade on the data definition that stores a similar template name/slug.

laurenhamel commented 5 years ago

@kristianserrano, I wanted to add a little more insight here about how the templating engine is currently configured to handle routing, based on the points you've given. This may also help the others understand what's going on behind the scenes as well but will mostly influence how we decide to implement dynamic routes:

  1. Since our site-specific domain folders will be the entry point into our entire templating engine architecture, the way the templating engine is currently setup, it expects that each site will have an .htaccess file that forces all incoming requests to point to the site's index.php (forced redirects are handled within the templating engine, which I will get to later). Then, within the site-specific index.php is where I'm currently defining some preliminary constants, like the site's environment (development, production, qa, or staging), its hostname (without the environment subdomain), and its full domain (with the environment subdomain, if applicable). From there, it uses these 3 constants to identify the appropriate paths to use for the site's data files, patterns, and templating engine (all of which get defined as constants). The last thing the index.php then does is require the templating engine's entry script (engine.php) to get the ball rolling.

  2. When the engine.php file is loaded, it looks at the constants that were previously defined in the site's index.php and builds out a set of configurations (also pulling in any prebuilt configuration files specific to the templating engine). These configurations are then used to index all relevant data that the site will have access to as well as all relevant patterns that the templating engine can use, and then takes this information and converts it into routes (along with any preconfigured route data found in the templating engine's own configuration files). The route is what's responsible for identifying the template file that should be used for a given data file: That is, it looks at the page type specified within the data file and matches it against a set of key-value pairs found in the templating engine's template.json configuration file (which gets preloaded into the engine's configuration data and basically matches up template slugs or IDs with the page type attribute in the XML files). Likewise, as it currently stands, the route is also what's responsible for determining if a route will redirect: It looks for a redirect key within the data file, assuming the value would identify another endpoint or URL that the route should point to.

  3. The templating engine then passes off this route data to its router, which then converts the routes into endpoints that will either (a) redirect (to another endpoint or URL), (b) render, or (c) result in a 404 error page (because the route doesn't exist). The templating engine then processes the incoming request to identify which endpoint was actually requested, and the router then routes the user accordingly.

Thus, in terms of where dynamic routes may come into play, I'm either thinking that this can go one of two ways:

  1. We embed the dynamic routes into the templating engine's routes, but immediately, I can think of some downsides of this approach: (a) It's not transparent and limits future scalability (requires manual adjustments each time we need to make a change to a dynamic endpoint), and (b) it would likely cause interference with the way data-driven routes are identified (via the process above), which means we'd have to go back yet again and reengineer the way we're building the routes.

  2. The other alternative that I was thinking may be a more flexible option and better all-around approach would be to setup some sort of "dynamic" page type within the CMS. In doing so, (a) it would help transparently identify which endpoints are dynamic, and (b) it would still work within the templating engine's current setup, where all we would need to do is add in some additional logic with regards to how the dynamic routes are processed and handled. Within the CMS, this would also give content editors the flexibility of identifying when data is dynamic as well as the ability to select which folder of data the dynamic endpoint would use (the two main points of information we'd need in the templating engine).

laurenhamel commented 5 years ago

Adding onto my last comment too, as I've been working on the templating engine, I'm simultaneously trying to build out a set of "schematics" that helps to clarify how the templating engine works. I can share that with you all sometime tomorrow.

kristianserrano commented 5 years ago

OK, that all makes sense now. I think the second option could work really well. In fact, it all made me think of Craft's routing mechanisms, including maintaining routes in the CMS itself. We could even have a field that tells the engine which template to use.

laurenhamel commented 5 years ago

I'm looking at the current IA in Cascade in comparison to the Figma templates, and I'm thinking that we should probably just identify certain page types as dynamic (i.e., services directory will be dynamic). That way, content editors can just insert the appropriate page type into the IA instead of trying to figure out what the page type or template type might need to be for a given page. That will also allow us to then identify the appropriate template based on the page type, and within the data definition, we can allow for content editors to provide one or more paths to folders containing the data files to use to build out the dynamic routes. For now, I'm also thinking that we can just operate under the assumption that dynamic routes will only include one-level of depth (i.e., services/:service rather than services/:category/:service). @kristianserrano, if you're okay with this, I can go ahead and start implementing in the templating engine, and we can add in the data definitions into Cascade at some point.

laurenhamel commented 5 years ago

Another thought I just had is that we also need to consider how this dynamic data will be passed along to other pages that may not be dynamic themselves but will use the dynamic page data (i.e., library aid cards in other pages). Again, I'm thinking this will need to be something we're indexing, but feel free to share your thoughts here.

kristianserrano commented 5 years ago

Yes, I wholly agree. Even if that page type is just a uniquely named page type with just metadata fields for page title and description, and a version field for future development, that's all it really needs to be.

kristianserrano commented 5 years ago

Library aid cards will be links to actual library aid pages. Do you have other examples?

laurenhamel commented 5 years ago

My thought was that we may need that dynamic data for building cards, but if we're treating those as links, then never mind. As far as the dynamic pages go, though, should we also assume that all content within the same IA directory, including any sub-directories, will make up the dynamic routes, or will there ever be a use case for needing to reference data somewhere else in the IA (e.g., I believe at one point, the site map had library aids split between Using the Library and Research)? If there is a use case for the latter, then it makes sense to have an actual dynamic page type because then we're wanting to "alias" pages from other parts of the site as if it were a child page of the current section. However, if you don't think there's a use case for the latter, we likely can scrap the idea of dynamic routes all together in favor of maybe a handlebars helper that just lets us retrieve the contents of the current directory and/or sub-directories, and work that into how we build out the templates for these "dynamic" pages.

kristianserrano commented 5 years ago

Last @nikdragovic and I spoke, the Library Aids will be all stored in a root-level subdirectory and collected together there. We'll probably need a combination of pulling content of a specific type within a subdirectory which in theory should be faster than checking the entire index.