Help with documentation for a new MODX Site

I’m building a new MODX site for an academic library. I am working on the design guide/documentation section of the site. Currently permissions only allow those logged into the manager to see the design guide(so I cannot share a link) I will not be managing the content.

Does anyone have suggestions or examples for documenting the various Templates used on the site?

I am thinking the Template docs should include the following sections

  • Usage
  • Template Variables
  • Link to a page using the template

Am I missing any info that might be useful.

Thanks in advance for any advice.

Roy

That sounds good. Since the Template list and the list of TVs for each one will probably change with some regularity, I would suggest automating the Template/TV listing with a custom snippet. It’s not terribly difficult, and would ultimately save you a lot of time. It could also automatically include each Template’s description, and make its name a link to the example page.

@bobray
Thanks for the suggestion. I do not currently program very much in php any more and I do not know the MODX API very well. I but I was reading some of your blog posts on extracting template information. So I might tackle this problem sometime in the near future.

I think this would be a great topic to tackle in your blog postings. Not just the template docs, but anyway to automate creation of documentation for a site. Now that I occasionally build sites that others manage the content, I am focusing more on documenting the site’s design. It helps the content editors for the site greatly.

Roy

I have a script that outputs the templates and their descriptions in a

list.

<?php
/* Code Stolen from BobRay's TemplateReportPlus snippet */

	/* Make it run in either MODX 2 or MODX 3 */
	$prefix = $modx->getVersionData()['version'] >= 3
	  ? 'MODX\Revolution\\'
	  : '';

$templates = $modx->getCollection($prefix . 'modTemplate');


$output='<dl>';

foreach ($templates as $template) {
	$id = $template->get('id');
	$name = $template->get('templatename');
	$desc = $template->get('description');

	$output .= '<dt>' . $name . '</dt><dd class="mb-5">' . $desc . '</dd>' ;

}
$output .="</dl>";

return $output;

Now I’d like to display that TemplateVariables for each template.
I know that the code will be just getting the TVs for each template and them looping through them with a foreach loop

Here is my rough idea of pseudocode for that part of the snippet. Can anyone help with how to get the TVs for a template and How to get the name, caption, and description?

$tvs = $template->get('TVS');
foreach ($tvs as $tv){
    $TVname = TVName;
    $TVcaption = TVCaption;    
    $TVdesc = TVdescription;

   $output .= TVname . TVcaption . TVdesc
}

Thanks,
Roy

It sounds logical to to get the template’s TVs directly, but I don’t think you can do it without more complex code.

It’s a two-step process. First, you get the Template object’s related modTemplateVarTemplate objects (this is all indented inside your foreach loop after your existing code):

$tvts = $modx->getCollection($prefix . 'modTemplateVarTemplate', array('templateId' => $id));

/* Inner loop */
$doneAlready = array(); // We'll use this to skip duplicates

$output .= '<br>Template Variables';
foreach ($tvts as $tvt) {
    $tvId = $tvt->get('tmplvarid');
    if (in_array($tvId, $doneAlready)){
        continue;
}
    $doneAlready[] = $tvId;
    $tvObject = $modx->getObject($prefix . 'modTemplateVar',
        array('id' => $tvId));

    $TvName = $tvObject->get('name');
    $TvDesc = $tvObject->get('description');

    $output .= '<br >&nbsp;&nbsp *' . $TvName .
        '<br>&nbsp;&nbsp' . $TvDesc;
} /* End of inner loop */

This is all off the top of my head, so there may be some mistakes. I’ve left the CSS formatting up to you. (do it after it works).

I think it’s possible to get all this with one getCollectionGraph() call and for sure a much faster way would be a straight. somewhat complex, PDO call but it would be tricky to get it right and eliminate the duplicates, and I’m too tired to work it out.

A different, slightly easier method would be to use the relationships from the schema with getMany/getOne:

$tvts = $template->getMany("TemplateVarTemplates");

$output .= '<br>Template Variables';
foreach ($tvts as $tvt) {
    $tvObject = $tvt->getOne("TemplateVar");

    $TvName = $tvObject->get('name');
    ...
}

Thank you @bobray, @halftrainedharry and @matdave for all your help.

Here is my final code that works just great. Sorry for the inline HTML and Bootstrap classes, I know that it should use templating.

I hope this code is useful to others when adding documentation to. site.

Roy

<?php
/* Snippet: template-documentation */
/* Generates Documentation for all Template */
/* Displays the following informaiton */
/*      Template Name and Description */
/*      TVS- Caption, tag, and description */


/* Make it run in either MODX 2 or MODX 3 */
$prefix = $modx->getVersionData()['version'] >= 3
  ? 'MODX\Revolution\\'
  : '';

/* Get the list of templates */
$templates = $modx->getCollection($prefix . 'modTemplate');

/* Create empty output var */
$output='';

/* Loop through Templates */
foreach ($templates as $template) {
	$id = $template->get('id');
	$name = $template->get('templatename');
	$desc = $template->get('description');

	/* Generate formatted output for each template */
	$output .= '<div class=" mb-5">'; //template wrapper
	
		$output .= '<h3>' . $name . '</h3>'; 
		$output .= '<p class="lead">' . $desc . '</p>' ; 
	
		$output .='<div class="ms-5 mb-4">';//TV section wrapper
			$output .= '<h4>Template Variables</h4>'; 
			$tvts = $template->getMany('TemplateVarTemplates');
			foreach ($tvts as $tvt){
				$tv = $tvt->getOne('TemplateVar');
						
				$output .= '<div class="ms-4">'; //TV wrapper
					$output .=  '<p><strong>' . $tv->get('caption')  . '</strong><br>';
					$output .=  'Tag: ' . $tv->get('name')  . '<br>';
					$output .=  'Desc: ' . $tv->get('description')  . '</p>';
				$output .=  '</div>';	// end tv wrapper
			}	
		$output .=  '</div>'; //end tv-section wrapper
	$output .=  '</div>'; //end template wrapper
}
return $output;

halftrainedharry’s simpler method is how I first wrote it, but it seemed to me that it would produce duplicates in the TV list. On second thought, I don’t think it will, so it’s a better approach.