<p>You can't and it's a good thing. Your external JS file is meant to be static so it can be cached by the visitors' browser.</p>
<p>One way to achieve what you want is to only define the <code>addToMap()</code> function in your external JS file and call this function from your template, passing it the locations to display.</p>
<p>Here's how you can do this from your template:</p>
<pre><code>{% if entry.lotInfo|length %}
  {# Create a Twig array to store locations #}
  {% set locations = [] %}
  {% for row in entry.lotInfo %}
    {% if row.createNewEntry == '1' %}
      {# Add an entry in the locations Twig array #}
      {% set locations = locations|merge([{ lat: row.latitude, lng: row.latitude }]) %}
    {% endif %}
  {% endfor %}

  {% if locations is not empty %}
    {# Create a JS block at the end of &lt;body&gt; #}
    {% js %}
      {# call the JS function addToMap, passing it a json_encoded version of the locations Twig array #}
      addToMap({{ locations|json_encode|raw }})
    {% endjs %}
  {% endif %}
{% endif %}
</code></pre>
<p><strong>Reference:</strong></p>
<ul>
<li><a href="https://craftcms.com/docs/3.x/dev/tags.html#js" rel="nofollow noreferrer"><code>js</code> Twig tag</a></li>
<li><a href="https://craftcms.com/docs/3.x/dev/filters.html#json-encode" rel="nofollow noreferrer"><code>json_encode</code> Twig filter</a></li>
<li><a href="https://twig.symfony.com/doc/2.x/filters/raw.html" rel="nofollow noreferrer"><code>raw</code> Twig filter</a></li>
<li><a href="https://twig.symfony.com/doc/2.x/filters/merge.html" rel="nofollow noreferrer"><code>merge</code> Twig filter</a></li>
</ul>

CC BY-SA 4.0
2020-10-05T15:34:30.617Z
Thank you for the in-depth response- I am now getting a "Variable "location" does not exist." pointing to this line " {% set locations = location|merge([{ lat: row.latitude, lng: row.latitude }]) %" I will review the references you provided but if you have any other ideas it would be greatly appreciated, I am having some difficulty wrapping my head around Twig.
Gideon B
CC BY-SA 4.0
2020-10-05T15:59:48.317Z
This is a typo, sorry about that. It should be `locations|merge`. I just edited my answer to correct the code.
nstCactus
CC BY-SA 4.0
2020-10-05T17:54:49.047Z
Thank you, I made the change and although the _entry.twig page loaded this time, the markers were still not output to the map on the _layout.twig, I read through your references above and I think I am having difficulty with how Twig and Javascript work together. I have an external script (./web/scripts.js) which contains the addToMap function linked in the _layout.twig file and _entry.twig is an extension of _layout.twig. So although the page has loaded, I can't help but feel there is something I am not grasping that puts it all together. I appreciate your help with this.
Gideon B
CC BY-SA 4.0
2020-10-05T19:42:08.533Z
I guess the part I am most confused on is this part "define the addToMap() function in your external JS file and call this function from your template, passing it the locations to display." I am no longer getting any errors but the function in my external script is not outputting anything to the map on the _layout.twig page? Any clarification on this part wouild be greatly appreciated.
Gideon B
CC BY-SA 4.0
2020-10-05T23:31:43.327Z
I cannot help you much more without seeing the content of your layout.twig and entry.twig, or even the rendered page source. You can start by having a look in your JS console to see if there are any errors there. Also make sure that, by the time the `addToMap()` function is called, the JS file in which its defined has already been loaded.
nstCactus
CC BY-SA 4.0
2020-10-08T23:00:08.780Z
Its been a couple days and still no luck. I implemented what you had mentioned but still no luck. I am able to get to a point where I am outputting an Array to the console on the _entry.twig page but still can't sort how to get that array to my _layout.twig where I can apply it to my js function. I have updated the code above with where I am currently and would appreciate any more help you can offer.
Gideon B
CC BY-SA 4.0
2020-10-05T10:15:45.937Z
2020-10-05T15:58:42.547Z
2020-10-05T15:58:42.547Z
nstCactus
<p>I have created a _layout.twig file which acts as my base to hold content on the page -&gt; _layout.twig:</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;{{ craft.app.language }}&quot;&gt;
  &lt;head&gt;
    &lt;meta content=&quot;IE=edge&quot; http-equiv=&quot;X-UA-Compatible&quot; /&gt;
    &lt;meta charset=&quot;utf-8&quot; /&gt;
    &lt;title&gt;
      {{ siteName }}
    &lt;/title&gt;
    &lt;meta content=&quot;width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover&quot;
      name=&quot;viewport&quot; /&gt;
    &lt;link rel=&quot;stylesheet&quot;
      href=&quot;https://unpkg.com/leaflet@1.4.0/dist/leaflet.css&quot;
      integrity=&quot;sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==&quot;
      crossorigin=&quot;&quot; /&gt;
    {% includeCssFile siteUrl ~ 'assets/css/style.css' %}
  &lt;/head&gt;
  &lt;body&gt;
    {% include '_includes/nav' %}
    &lt;div&gt;
      {% block content %}

      {% endblock %}
    &lt;/div&gt;
    &lt;footer class=&quot;main-footer&quot;&gt;
      &lt;div class=&quot;footer-wrapper&quot;&gt;
        {{ exampleInformation.exampleDescription|markdown }}
        &lt;p&gt;
          &amp;copy; {{ now|date('Y') }}, &lt;a href=&quot;https://craftcms.com&quot;&gt;Lorem Ipsum&lt;/a&gt;
        &lt;/p&gt;
      &lt;/div&gt;
    &lt;/footer&gt;
    &lt;script src=&quot;https://unpkg.com/leaflet@1.4.0/dist/leaflet.js&quot;   integrity=&quot;sha512QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg==&quot; crossorigin=&quot;&quot;&gt;&lt;/script&gt;
    {% includeJsFile siteUrl ~ 'assets/js/scripts.js' %}
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Through the control panel in craft CMS I created an entry  that contains a table that has a series of coordinates (longitude and latitude values) and a lightswitch to toggle it on or off, along with some other general information for each entry that is created e.g. title, date, image, etc. on a separate tab.</p>
<p>The _entry.twig page extends _layout.twig -&gt; _entry.twig:</p>
<pre><code>{% extends '_layout' %}

{% set featureImage = {
  mode: 'crop',
  width: 600,
  height: 600,
  quality: 90
} %}

{% block content %}
  &lt;div class=&quot;entry__container&quot;&gt;
    &lt;div class=&quot;entry__wrapper&quot;&gt;
      &lt;div class=&quot;entry__title&quot;&gt;
        &lt;h1&gt;
          {{ entry.title }}
        &lt;/h1&gt;
      &lt;/div&gt;

      &lt;div class=&quot;entry__image&quot;&gt;
        {% if entry.featureImage|length %}
          {% for image in entry.featureImage.all() %}
            &lt;img src=&quot;{{ image.getUrl(featureImage) }}&quot;
              alt=&quot;{{ image.title }}&quot; /&gt;
          {% endfor %}
        {% endif %}
      &lt;/div&gt;

      &lt;div&gt;
        {% for block in entry.exampleContent.all() %}
          &lt;div class=&quot;entry__description&quot;&gt;
            {% if block.type == 'text' %}
              {{ block.text }}
            {% elseif block.type == 'image' %}
              {% for image in block.image.all() %}
                &lt;img src=&quot;{{ image.url }}&quot; alt=&quot;{{ image.title }}&quot; /&gt;
              {% endfor %}
            {% endif %}
          &lt;/div&gt;
        {% endfor %}
      &lt;/div&gt;

      {# display post categories #}
      {% if entry.exampleCategories|length %}
        &lt;div class=&quot;entry__category&quot;&gt;
          &lt;p&gt;
            Categories
          &lt;/p&gt;
          {% for category in entry.exampleCategories.all() %}
            &lt;a href=&quot;{{ category.url }}&quot;&gt;{{- category.title -}}&lt;/a&gt;
          {% endfor %}
        &lt;/div&gt;
      {% endif %}

      {# display table info #}
      {% if entry.lotInfo|length %}
        {# Create a Twig array to store locations #}
        {% set locations = [] %}
        {% for row in entry.lotInfo %}
          {% if row.createNewEntry == '1' %}
            {# Add an entry in the locations Twig array #}
            {% set locations = locations|merge([{ lat: row.latitude, lng: row.longitude }]) %}
          {% endif %}
        {% endfor %}

        {% if locations is not empty %}
          {# Create a JS block at the end of &lt;body&gt; #}
          {% js %}
            {# call the JS function addToMap, passing it a json_encoded version of the locations Twig array #}
            addToMap({{ locations|json_encode|raw }})
          {% endjs %}
        {% endif %}
      {% endif %}
      {# end table info #}
      {% js %}
      &lt;script type=&quot;text/javascript&quot;&gt;
        var coordinates = {{ locations | json_encode | raw }};
        console.log(coordinates);
      &lt;/script&gt;
      {% endjs %}
    &lt;/div&gt;
  &lt;/div&gt;
{% endblock %}
</code></pre>
<p>I was able to put together this small section in _entry.twig which looks at the table and if the lightswitch is set to 1, it outputs the corresponding latitude and longitude values in the row:</p>
<pre><code>{# display table info #}
      {% if entry.lotInfo|length %}
        &lt;div class=&quot;entry__coordinate&quot;&gt;
          &lt;ul&gt;
            {% for row in entry.lotInfo %}
              {% if row.createNewEntry == '1' %}
                &lt;li&gt;
                  &lt;div data-latCoordinate=&quot;{{ row.latitude }}&quot;
                    id=&quot;latCoordinate&quot;&gt;
                    {{ row.latitude }}
                  &lt;/div&gt;,&lt;div data-lngCoordinate=&quot;{{ row.longitude }}&quot;
                    id=&quot;lngCoordinate&quot;&gt;
                    {{ row.longitude }}
                  &lt;/div&gt;
                &lt;/li&gt;
              {% endif %}
            {% endfor %}
          &lt;/ul&gt;
        &lt;/div&gt;
      {% endif %}
      {# end table info #}
</code></pre>
<p>These values are currently displaying on the front end entry page which will show the coordinates depending on which lightswitch toggle is active- which has allowed me to ensure that it is pulling the correct coordinates corresponding to the correct information.</p>
<p>Now, I have an external js file linked which lives in local/craft/assets/js/*.js and contains this script -&gt; scripts.js:</p>
<pre><code>//Set initial map view

var map = L.map('map', { scrollWheelZoom: false }).setView(
  [50.4205, -104.52],
  15,
)

//Initialize the tilemap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  maxZoom: 19,
  minZoom: 14.5,
  attribution:
    '&amp;copy; &lt;a href=&quot;https://www.openstreetmap.org/copyright&quot;&gt;OpenStreetMap&lt;/a&gt; contributors',
}).addTo(map)

// Set location array
var locations = [{ lat: 'SOME LATITUDE COORDINATE', lng: 'SOME LONGITUDE COORDINATE' }]

function addToMap(locationArray) {
  //Iterate through array object
  ;[].forEach.call(locationArray, function (location) {
    var marker = L.marker([location.lat, location.lng]).addTo(map)
  })
}
//Show markers
addToMap(locations)
</code></pre>
<p>Currently, this script will create a leaflet/osm map and then based on:</p>
<pre><code>// Set location array
var locations = [{ lat: '(SOME LATITUDE VALUE)', lng: '-(SOME LONGITUDE VALUE') }];
</code></pre>
<p>will output a marker to the map (currently only outputs a marker if I manually insert lat and long coordinates) which lives in my index.twig template file -&gt; index.twig:</p>
<pre><code>{% extends '_layout' %}
{% set posts = craft.entries.section('example').all() %}
{% block content %}
  &lt;div class=&quot;background-test&quot;&gt;
    &lt;div id=&quot;map&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;main-container&quot;&gt;
    &lt;div class=&quot;main-wrapper&quot;&gt;
      &lt;h1 class=&quot;example-title&quot;&gt;
        Some Title
      &lt;/h1&gt;
      &lt;div class=&quot;category-list&quot;&gt;
        {% set entries = craft.entries.limit(null) %}
        {% for category in craft.categories.relatedTo(entries).order(
          'title asc'
        ) %}
          {% set entryCount = entries.relatedTo(category).total() %}
          &lt;a href=&quot;{{ category.url }}&quot;&gt;
            {{- category.title -}}&lt;span class=&quot;count-number&quot;&gt;({{ entryCount }})&lt;/span&gt;
          &lt;/a&gt;
        {% endfor %}
      &lt;/div&gt;
      {% include '_includes/listing' with {
        posts: posts
      } only %}
    &lt;/div&gt;
  &lt;/div&gt;
{% endblock %}
</code></pre>
<p>What would be the best way to somehow use the</p>
<pre><code>{{ row.latitude }}, {{ row.longitude }}
</code></pre>
<p>variables from my _entry.twig file in my existing scripts.js file to place a marker(s) on the map which lives on the index.twig page? I am still new to Craft and more so with Twig so I am still in the process of learning these things.</p>
<p>My folder structure is:</p>
<pre><code>/assets
   /css
   /js
      scripts.js
/templates
   /includes
   /blog
      _category.twig
      _entry.twig
       index.twig
   _layout.twig
   index.html

Any help would be greatly appreciated!

Thank you
</code></pre>

<craft3><templating><entry><javascript><craft-pro>
Input and Use Twig Variable in External JS Script Across Different Pages
# Input and Use Twig Variable in External JS Script Across Different Pages

(Asked by: username_0 on 2020-10-02)

I have created a _layout.twig file which acts as my base to hold content on the page -> _layout.twig:


  
    
    
    
      {{ siteName }}
    
    
    
    {% includeCssFile siteUrl ~ 'assets/css/style.css' %}
  
  
    {% include '_includes/nav' %}
    
      {% block content %}

      {% endblock %}
    
    
      
        {{ exampleInformation.exampleDescription|markdown }}
        
          © {{ now|date('Y') }}, Lorem Ipsum
        
      
    
    
    {% includeJsFile siteUrl ~ 'assets/js/scripts.js' %}
  


Through the control panel in craft CMS I created an entry  that contains a table that has a series of coordinates (longitude and latitude values) and a lightswitch to toggle it on or off, along with some other general information for each entry that is created e.g. title, date, image, etc. on a separate tab.
The _entry.twig page extends _layout.twig -> _entry.twig:
{% extends '_layout' %}

{% set featureImage = {
  mode: 'crop',
  width: 600,
  height: 600,
  quality: 90
} %}

{% block content %}
  
    
      
        
          {{ entry.title }}
        
      

      
        {% if entry.featureImage|length %}
          {% for image in entry.featureImage.all() %}
            
          {% endfor %}
        {% endif %}
      

      
        {% for block in entry.exampleContent.all() %}
          
            {% if block.type == 'text' %}
              {{ block.text }}
            {% elseif block.type == 'image' %}
              {% for image in block.image.all() %}
                
              {% endfor %}
            {% endif %}
          
        {% endfor %}
      

      {# display post categories #}
      {% if entry.exampleCategories|length %}
        
          
            Categories
          
          {% for category in entry.exampleCategories.all() %}
            {{- category.title -}}
          {% endfor %}
        
      {% endif %}

      {# display table info #}
      {% if entry.lotInfo|length %}
        {# Create a Twig array to store locations #}
        {% set locations = [] %}
        {% for row in entry.lotInfo %}
          {% if row.createNewEntry == '1' %}
            {# Add an entry in the locations Twig array #}
            {% set locations = locations|merge([{ lat: row.latitude, lng: row.longitude }]) %}
          {% endif %}
        {% endfor %}

        {% if locations is not empty %}
          {# Create a JS block at the end of  #}
          {% js %}
            {# call the JS function addToMap, passing it a json_encoded version of the locations Twig array #}
            addToMap({{ locations|json_encode|raw }})
          {% endjs %}
        {% endif %}
      {% endif %}
      {# end table info #}
      {% js %}
      
      {% endjs %}
    
  
{% endblock %}

I was able to put together this small section in _entry.twig which looks at the table and if the lightswitch is set to 1, it outputs the corresponding latitude and longitude values in the row:
{# display table info #}
      {% if entry.lotInfo|length %}
        
          
            {% for row in entry.lotInfo %}
              {% if row.createNewEntry == '1' %}
                
                  
                    {{ row.latitude }}
                  ,
                    {{ row.longitude }}
                  
                
              {% endif %}
            {% endfor %}
          
        
      {% endif %}
      {# end table info #}

These values are currently displaying on the front end entry page which will show the coordinates depending on which lightswitch toggle is active- which has allowed me to ensure that it is pulling the correct coordinates corresponding to the correct information.
Now, I have an external js file linked which lives in local/craft/assets/js/*.js and contains this script -> scripts.js:
//Set initial map view

var map = L.map('map', { scrollWheelZoom: false }).setView(
  [50.4205, -104.52],
  15,
)

//Initialize the tilemap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  maxZoom: 19,
  minZoom: 14.5,
  attribution:
    '© OpenStreetMap contributors',
}).addTo(map)

// Set location array
var locations = [{ lat: 'SOME LATITUDE COORDINATE', lng: 'SOME LONGITUDE COORDINATE' }]

function addToMap(locationArray) {
  //Iterate through array object
  ;[].forEach.call(locationArray, function (location) {
    var marker = L.marker([location.lat, location.lng]).addTo(map)
  })
}
//Show markers
addToMap(locations)

Currently, this script will create a leaflet/osm map and then based on:
// Set location array
var locations = [{ lat: '(SOME LATITUDE VALUE)', lng: '-(SOME LONGITUDE VALUE') }];

will output a marker to the map (currently only outputs a marker if I manually insert lat and long coordinates) which lives in my index.twig template file -> index.twig:
{% extends '_layout' %}
{% set posts = craft.entries.section('example').all() %}
{% block content %}
  
    
  
  
    
      
        Some Title
      
      
        {% set entries = craft.entries.limit(null) %}
        {% for category in craft.categories.relatedTo(entries).order(
          'title asc'
        ) %}
          {% set entryCount = entries.relatedTo(category).total() %}
          
            {{- category.title -}}({{ entryCount }})
          
        {% endfor %}
      
      {% include '_includes/listing' with {
        posts: posts
      } only %}
    
  
{% endblock %}

What would be the best way to somehow use the
{{ row.latitude }}, {{ row.longitude }}

variables from my _entry.twig file in my existing scripts.js file to place a marker(s) on the map which lives on the index.twig page? I am still new to Craft and more so with Twig so I am still in the process of learning these things.
My folder structure is:
/assets
   /css
   /js
      scripts.js
/templates
   /includes
   /blog
      _category.twig
      _entry.twig
       index.twig
   _layout.twig
   index.html

Any help would be greatly appreciated!

Thank you

**Tags:** craft3, templating, entry, javascript, craft-pro

---

## 1 answers

### Answer by username_1 on 2020-10-05. Score: 2

You can't and it's a good thing. Your external JS file is meant to be static so it can be cached by the visitors' browser.
One way to achieve what you want is to only define the addToMap() function in your external JS file and call this function from your template, passing it the locations to display.
Here's how you can do this from your template:
{% if entry.lotInfo|length %}
  {# Create a Twig array to store locations #}
  {% set locations = [] %}
  {% for row in entry.lotInfo %}
    {% if row.createNewEntry == '1' %}
      {# Add an entry in the locations Twig array #}
      {% set locations = locations|merge([{ lat: row.latitude, lng: row.latitude }]) %}
    {% endif %}
  {% endfor %}

  {% if locations is not empty %}
    {# Create a JS block at the end of  #}
    {% js %}
      {# call the JS function addToMap, passing it a json_encoded version of the locations Twig array #}
      addToMap({{ locations|json_encode|raw }})
    {% endjs %}
  {% endif %}
{% endif %}

Reference:

js Twig tag
json_encode Twig filter
raw Twig filter
merge Twig filter

> **Comments:**
> **username_0**: Thank you for the in-depth response- I am now getting a "Variable "location" does not exist." pointing to this line " {% set locations = location|merge([{ lat: row.latitude, lng: row.latitude }]) %" I will review the references you provided but if you have any other ideas it would be greatly appreciated, I am having some difficulty wrapping my head around Twig.  
> **username_1**: This is a typo, sorry about that. It should be `locations|merge`. I just edited my answer to correct the code.  
> **username_0**: Thank you, I made the change and although the _entry.twig page loaded this time, the markers were still not output to the map on the _layout.twig, I read through your references above and I think I am having difficulty with how Twig and Javascript work together. I have an external script (./web/scripts.js) which contains the addToMap function linked in the _layout.twig file and _entry.twig is an extension of _layout.twig. So although the page has loaded, I can't help but feel there is something I am not grasping that puts it all together. I appreciate your help with this.  
> **username_0**: I guess the part I am most confused on is this part "define the addToMap() function in your external JS file and call this function from your template, passing it the locations to display." I am no longer getting any errors but the function in my external script is not outputting anything to the map on the _layout.twig page? Any clarification on this part wouild be greatly appreciated.  
> **username_1**: I cannot help you much more without seeing the content of your layout.twig and entry.twig, or even the rendered page source. You can start by having a look in your JS console to see if there are any errors there. Also make sure that, by the time the `addToMap()` function is called, the JS file in which its defined has already been loaded.  
> **username_0**: Its been a couple days and still no luck. I implemented what you had mentioned but still no luck. I am able to get to a point where I am outputting an Array to the console on the _entry.twig page but still can't sort how to get that array to my _layout.twig where I can apply it to my js function. I have updated the code above with where I am currently and would appreciate any more help you can offer.  

---

