How to create dynamic content using a CSV datasource


(Veryphatic) #1

Hi all, I recently created a page that let users search a datasource via a form and return the results. There were a few steps, and some undocumented parts that I've put into the following tutorial:

 

 

How to create dynamic content using a CSV datasource

 

The purpose of this tutorial is to provide the details for you to generate a dynamic content area using a CSV datasource. By dynamic I mean the ability to isolate individual shadow assets and present these, exclusive of other assets in the datasource.

 

For example, say we have a CSV file containing a list of books you have available in your store. In the CSV you have a number of columns that store information about each book – Book title, Publish year, Publisher, Author, ISBN.

 

With this data we will create two different ways to generate dynamic content based on user interaction, in our example we’ll use a form to search for content in one of the columns.

 

 

Prepare and upload the CSV

 

  1. First prepare your CSV file ensuring you have clearly defined columns. Also check to make sure you don’t have extra spaces in the rows and columns. Extra spacing will cause PHP errors in Matrix when you upload the CSV file.
  2. Upload the CSV into Matrix using the CSV datasource
  3. Take note of the Available Keywords For the Data Source Record Set Asset in the Shadow Asset Name section of the details screen. You’ll need them later. For reference we want the following Keywords
    1. %ds__book_title%
    2. %ds__publish_year%
    3. %ds__publisher%
    4. %ds__author%
    5. %ds_isbn%

 

 

Create and prepare an Asset Listing Page

 

  1. Create a new Asset Listing Page asset
  2. In the Asset Selection section in the details screen, choose Data Source Record Set for the Asset Types to List.
  3. In the Asset Locations section on the details screen, choose the CSV datasource for the Root Nodes.

 

Prepare the CSV datasource to accept dynamic inputs

 

Before we follow these steps a little explanation of what we’re going to do here.  In order to create dynamic content, what we’re essentially doing is filtering the CSV file and returning the values via the asset listing asset.

 

There are two parts that allow us to filter the CSV, first we need to create a filter with a range of conditions; then we need to create a dynamic input, that allows us to pass the value to the filter.

 

Creating the Record Filter

 

For our first example we want to create a form that searches the Publish year. To do this we’ll create the condition that allows us to search just this column.

 

  1. From the context menu of the CSV datasource select Record Filter
  2. Create a new condition by entering a name in the Add New Condition text input. This input needs to match the name of the datasource record set field name. So for our example, we’ll call ours publish_year.  Click commit.
  3. Now set the remaining conditions:
    1. Value to match: %%year_search_value%%
    2. Match type: String match – Exact
    3. Match case: No
  4. Turn the filter on by adjusting the Filter Options section to:
  5. Filter status: On
  6. Logical Grouping: Match on ONE condition
  7. Filter Mode: Return the records matching the given conditions

 

You’ll notice the double %% signs being used in the Match type. This value is the name we’re going to use in our Dynamic Input, as per the notice at the bottom of the section:

 

Note: Dynamic variables added in "Dynamic Inputs" screen can be used here in the "Value to Match" field in the form %%VARIABLENAME%%.

 

Creating the Dynamic Input

 

Here we’ll create a dynamic input that grabs the value from our search form and store the value in the variable name we specified in the Record Filter.

 

  1. From the context menu of the CSV datasource select Dynamic Inputs
  2. In the Add New Variables Below text field in the Dynamic Variables section, add the variable name year_search_value and commit the change
  3. In the Data Mappings section, choose the parameter Variable: year_search_value and in the next selection list choose Set Variable, as we want to set the variable ‘year_serach_value’ with a value. Click commit to make the change.
  4. After the commit you’ll notice there is a blank field in the Data Mappings section that asks to Set Value. Here we’re going to use a Global Keyword Replacement to pull the value based on a URL parameter we’ll add to our form and link later. For now, enter the value %globals_get_year_query%

 

Building a search form

 

In this section we’ll create a form that asks generates a list of books published on a date given by the user.

 

  1. First create a standard page and create a form using the following HTML:
    <form action=”./?a=1234” method="get">
    <div class="form-actions">
    <label for="year_query">Enter a year to search for:
    <input type="text" name="year_query" /></label>
    <button type="submit">Search</button>
    </div>
    </form>

    You’ll notice we set the form action to another asset number. The number you enter here should be the number of the Asset Listing Page we created earlier. When we submit our form the value entered in the input named year_query will be appended to the URL, for example ?year_query=2012
     
  2. Next we need to setup the Asset Listing Page, so that the book information stored in the CSV is presented on the page.  For our application we want to present all of our data in a table.

    First in the Page Contents of our Asset listing Page we’ll create the table HTML. Enter:

    <table>
    <tr>
    <td>Publish year</td>
    <td>Title</td>
    <td>Author</td>
    <td>Publisher</td>
    <td>ISBN</td>
    </td>
    %asset_listing%
    </table>
     
  3. Now we need to put the datasource values into the table row. This is where we’ll need to reuse the datasource keywords we identified after uploading the CSV.

    <tr>
    <td>%ds__publish_year%</td>
    <td>% ds__book_title %</td>
    <td>% ds__author %</td>
    <td>% ds__publisher %</td>
    <td>% ds_isbn %</td>
    </td>

 

That’s pretty much it. Now when we search for a year using our form, we’ll append the year_query variable tour the URL, which we’ll grab from the Global Keyword Replacement as a Dynamic Input which is then used to filter our results, returning only the book information that matches the publish date entered.

 

Returning results in alphabetical order

 

If you want to return the books in alphabetical order you can do so by making a small adjustment to the CSV Datasource. This change will mean that the results will always return in alphabetical order for the Asset Listing Page used. Otherwise, there is no other way to order CSV datasource records other than using a JavaScript solution.

 

  1. Open the Details screen of your CSV datasource
  2. In the section Shadow Asset Name enter the value %ds__book_title% in the Enter The Name Of The Shadow Assets text input
  3. Head over to your Asset Page Listing and open the Asset Sorting page
  4. On this page adjust the default is to sort by Name, so unless you’ve made a change the results should now be sorted alphabetically. Otherwise in the Default Sorting section, set the Default Sort-by Option to Name or Short Name
     

 

After thoughts

 

This method could easily be applied to search a second table in a faceted style list, where values from one table can be used to filter the results of a second table. For this we could use a standard Asset Page Listing and pull out the values, create a list of links and append a value to the link.

 

For example, <a href=”./?a=anotherassetlisting?query_var=%ds__first_table_var%”>Show these results</a>


(Bart Banda) #2

Good stuff Nathan, just as an additional note: Record filters were included in Matrix since version 4.10.1. So if you don't see the Record Filter option from the context menu, you might need a newer version: http://www.squizlabs.com/squiz-matrix/squiz-matrix-newsletter-388

Manuals page: http://manuals.matrix.squizsuite.net/data/chapters/db-data-source#Record-Filter-Screen


#3

Thanks very much for this!  I can get my datasource to display nice cheers =)

 

But I am having trouble with the dynamic filtering and it would be ace - not to use a JS solution. I'm so close I can smell it.

 

this my form

 

<form action="./?a=1137974" method="get"> <div class="form-actions">
<label for="start_time_query">Enter a time to search for:
<input type="text" name="start_time_query"/></label>
<button type="submit">Search</button>
</div>
</form>

 

 

 

Record filters Record Set Field Name

			Value to Match
		
			Match Type
		
			Match Case
		
			Allow Empty
		
			Delete?
	
			
		
			
		
			&#160;
		
			&#160;
		
			&#160;
		
			<p>				<p>&#160;			
	<p>&#160;<p>&#160;<p><strong>Dynamic Inputs</strong><p>&#160;<p>Variable name <strong>start_time_value</strong><p>&#160;<p><strong>Data mappings</strong><p>&#160;<p>Variable: <strong>start_time_value</strong><p>get variable name <strong>%globals_get_start_time_query%</strong><p>&#160;<p>&#160;<p><strong>Datasource keywords</strong><p>&#160;
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_date% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : date </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__date%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : date </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_start_time% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : start_time </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__start_time%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : start_time </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_end_time% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : end_time </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__end_time%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : end_time </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_stream% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : stream </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__stream%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : stream </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_theme% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : theme </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__theme%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : theme </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_topic% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : topic </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__topic%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : topic </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_venue_building% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : venue_building </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__venue_building%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : venue_building </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_room% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : room </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__room%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : room </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_presenter% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : presenter </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__presenter%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : presenter </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%data_source_record_set_facilitator% </span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : facilitator </span></span>			
	
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">%ds__facilitator%</span></span>			
		
			<p><span style="font-family:'times new roman', serif;"><span style="font-size:12pt;">Record Set Attribute : facilitator </span></span>			
	<p>&#160;<p>&#160;<p>Any assistance will be highly appreciated and met with High fives from afar and possibly a code dance.

(Mitchell Essex) #4

Hi Fuzzi

 

I was just doing this yesterday and just saw your post, I think the issue is in your data mapping set value.

 

Mine was only based on state so I am showing you the code I used

 

Form pointing to assetid of asset listing page

 

<form action="./?a=12345" method="get"> <label for="state_query">Select state
<select name="state_query">
<option selected>Select State</option>
<option value="ACT">Australian Capital Territory</option>
<option value="NSW">New South Wales</option>
<option value="NT">Northern Territory</option>
<option value="QLD">Queensland</option>
<option value="SA">South Australia</option>
<option value="TAS">Tasmania</option>
<option value="VIC">Victoria</option>
<option value="WA">Western Australia</option>
</select>
<button type="submit">Search</button>
</form>

 

Asset listing

showing states from CSV data

 

Filter on CSV data source

 

[attachment=721:filter.png]

 

Dynamic variables the set value is %globals_get_state_query%

[attachment=720:dynamic.png]

  dynamic.png (59.8 KB) filter.png (77.1 KB)


#5

Thanks Mitch, I'm going to give this a burl! much appreciated you shared your code here, Ive tried bits of everyone's suggestions and I think between each suggestion think I altered it slightly off the mark each time.

 

Your filter image is the same as your data mappings one would you have just had

 

ds__state with a value of %%state%%

 

or would you have had to have

ds__state with a value of %%state_search_value%%

 

cheers!


(Mitchell Essex) #6

Sorry looks like my crop and save process wasn't quite up to scratch. 

 

Here is the filtered image

 

[attachment=722:filter2.png]

 

So we have 

state with a value of %%state_search_value%% filter2.png (83.9 KB)


#7

Thanks Mitch!  that's working

I had ds__start_time in my filter

I remove the __ds and it worked

 

thanks so much!!!

god that was doing my head in!


(Mitchell Essex) #8

No worries glad to help.


(Clementoke) #9

Any tips on how to do this pre-content filter versions? I'm trying to do something similar in version 4.6


(Jgraham) #10

Just done this, here are a few points that might help others.

  1. In the Asset Locations section on the details screen, choose the CSV datasource for the Root Nodes.

 

Be sure to actually change it under Asset Locations, I mistaked that name for Structured Root Selector Options (it had the same option).

 

Asset Locations is near the middle , and Structured Root selector is down the bottom. Took me awhile to figure it out.

 

Now we need to put the datasource values into the table row. This is where we’ll need to reuse the datasource keywords we identified after uploading the CSV.

 

This area, I believe is the "Default Format" asset under "Type Formats".

 

So page contents is this (also put into raw html mode as well):

 

<table><tr>
<td>Publish year</td>
<td>Title</td>
<td>Author</td>
<td>Publisher</td>
<td>ISBN</td>
</tr>
%asset_listing%
</table>

 

and in "Default Format", (raw html) put:

 

<tr>
<td>%ds__publish_year%</td>
<td>%ds__book_title%</td>
<td>%ds__author%</td>
<td>%ds__publisher%</td>
<td>%ds_isbn%</td>
</tr>

 

if you try to put the "ds" keywords in the page contents by mistake, it will come up blank.

 

Thanks for the guide and tips everyone.