Resources



Generator

  • additions to the generator, only needed to add files under ResourceFiles
  • (notice how our additions have reduced from original, to datamodel, to client), put in a final section
  • html without extension, hack so we can view contemporary url routes

gen/server.cue

		// Generator definition
#HofGenerator: gen.#HofGenerator & {
	// Define the resource Files
	ResourceFiles: [...gen.#File] & [
			// REST handlers, as before
			// HTML content
			for _, R in In.Resources {
			In: {
				RESOURCE: R
			}
			TemplatePath: "resource.html"
			Filepath:     "\(Outdir)/client/\(strings.ToLower(In.RESOURCE.Name))"
		},
		// HTML content
		for _, R in In.Resources {
			In: {
				RESOURCE: R
			}
			TemplatePath: "resource.js"
			Filepath:     "\(Outdir)/client/\(strings.ToLower(In.RESOURCE.Name)).js"
		},
	]
}

Initial HTML / JS

Since we broke down index.html into a number of partials, we can reuse them here and end up with a template for resource html which is very close to our index page.

templates/resource.html

{{ template "header.html" . }}
<div class="main">
  {{ template "navbar.html" . }}

  <div class="container pt-3">
    <div class="row">
      <h3>
        {{ $.RESOURCE.Name }}s
      </h3>
    </div>
    <div class="row">
      <pre id="data">
        <!-- we'll add the actual data here in JS -->
      </pre>
    </div>
  </div>
</div>

<script src="/{{ kebab $.RESOURCE.Name }}.js"> </script>
{{ template "footer.html" . }}

We will want to break this down into smaller snippets

  • talk about routes & query, list vs item views

templates/resource.js

document.addEventListener("DOMContentLoaded", function(event) {
  makeReq();
});

function makeUrl() {
  loc = window.location
  const urlSearchParams = new URLSearchParams(loc.search);
  const params = Object.fromEntries(urlSearchParams.entries());

  id = ""
  if (loc.search !== "") {
    id = "/" + params.{{ lower $.RESOURCE.Model.Index }}
  }

  url = "/api" + loc.pathname + id
  return url
}

function makeReq() {
  // where we put content
  elem = document.getElementById("data");

  url = makeUrl();

  // call API
  fetch(url).then(function(response) {
    return response.json().then(function(data){
      if (response.status >= 400) {
        throw data;
      }
      return data;
    })
  }).then(function(data) {
    renderData(data, elem)
  }).catch(function(error) {
    renderError(error, elem)
  });
}

function renderError(error, elem) {
  elem.innerHTML = error.message
}

function renderData(data, elem) {

  elem.innerHTML = JSON.stringify(data);

}

Rendering Resources

  • add templates for data rendering
  • templates in templates (2 options) & custom code additions
    • using alt delims in output, string replace
      • using alt delims in template, gen config (maybe we put this later, mention that it can be done and provide a link)
  • explain hack for using query (loc.search) for list vs item views

Fracturing the template into partials

  • break down JS template into partials
2022 Hofstadter, Inc