Create independent SVG files using Meteor and iron-router

My goal is to use Meteor and Iron-Router to serve dynamic SVG files with templating capabilities.

To start, I create a new route:

@route 'svg', {
   path: '/svg/:name'
   data: -> { name: this.params.name } # sample data
   layoutTemplate: 'svg'
}

Next, I set up a template:

<template name="svg">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
      xmlns:dc="http://purl.org/dc/elements/1.1/"
      xmlns:cc="http://creativecommons.org/ns#"
      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:svg="http://www.w3.org/2000/svg"
      xmlns="http://www.w3.org/2000/svg"
      version="1.1"
      width="500"
      height="500"
      id="svg2">
  <defs
        id="defs4" />
  <metadata
        id="metadata7">
    <rdf:RDF>
      <cc:Work
            rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
              rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
        transform="translate(0,-552.36218)"
        id="layer1">
    <text
     x="55.067966"
     y="838.08844"
     id="text2985"
     xml:space="preserve"
     style="font-size:108.92150116px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"><tspan
       x="55.067966"
       y="838.08844"
       id="tspan2987">{{name}}</tspan></text>
    </g>
  </svg>
</template>

When I navigate to http://localhost:3000/svg/foobar, I encounter the following error (in the browser):

Your app is crashing. Here's the latest log.

=> Errors prevented startup:

While building the application:
client/infrastructureViews/svg.html:2: Expected tag name after `<`
<?xml version="1.0" e...
 ^

=> Your application has errors. Waiting for file change.

Question: How can I instruct Meteor or Iron-Router not to generate the surrounding <html>... structure and recognize the SVG as a spacebars top-level element?

Answer №1

If you're looking to control how IR functions, unfortunately, that's not possible. However, you do have the option to switch to manual mode and create the response yourself.

To start, inform the router that a specific path will be handled on the server side:

this.route('svg', {
  path: '/svg/:name',
  where: 'server'
});

Next, set up a middleware on the server side to handle your response:

WebApp.connectHandlers.stack.splice(0, 0, {
  route: '/svg',
  handle: function(req, res, next) {
    var name = req.url.split('/')[1];    // Extract the parameter
    new Fiber(function () {              // Using Fiber is optional,
                                         // unless interaction with Mongo is required
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.write('Sample output');
      res.end();
    }).run()
  },
});

Note that you won't have access to the templating engine on the server side. To work around this, store your svg file in the /private directory, retrieve it as a text asset, and use underscore template format (e.g., <%= name %> instead of {{name}}) to populate it with data:

var template = Assets.getText('file.svg');
var output = _.template(template, {
  name: 'name',
});

Answer №2

After reading through @HubertOG's response and carefully reviewing the documentation for IronRouter, I have devised a new approach that solely utilizes IronRouter. This method involves incorporating both the where and action options:

Router.map ->
  @route 'svg',
    path: '/svg/:name'
    where: 'server'
    action: ->
      svgTemplate = Assets.getText('svg/drawing.svg')
      svg = _.template(svgTemplate, { name: @params.name })
      @response.writeHead(200, {'Content-Type': 'image/svg+xml'})
      @response.end(svg)

It is important to note that the corresponding SVG file must be stored within a subdirectory of /private, as using ../ does not appear to function in this scenario.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Efficiently organizing items within a list on Ionic

Currently, I have an ion-list structured as follows: <ion-list *ngFor = "let chat of Chats"> <ion-item (click) = "openChat(chat.id)"> <ion-label> <h2> {{chat.username}} </h2> ...

Javascript downloadable content available for download

<div class="center"data-role="content" id="content" > <a href="#flappy" data-transition="slide" >Avoid Becoming a Terrorist</a> </div> <div id="flappy" > <center> <div id="page"> ...

Real-time Data Stream and Navigation Bar Location

Utilizing the EventSource API, I am pulling data from a MySQL database and showcasing it on a website. Everything is running smoothly as planned, but my goal is to exhibit the data in a fixed height div, with the scrollbar constantly positioned at the bott ...

Setting multiple cookies with the setHeader method in NodeJs is a powerful capability that allows developers

Currently working on a project using node js, and I've encountered an issue with setting two different cookies. Every time I try to set them, the second cookie ends up overwriting the first one. Check out the code snippet below that I'm currently ...

Ways to display and conceal menu depending on initial view and scrolling

On my website, I have implemented two menus - one to be displayed when the page loads and another to show up when a scroll occurs. You can view my page here. The goal is to have the white part visible when the position is at the top, and switch to the blu ...

Vue.js Enhances CoolLightBox with Multiple Galleries

I am trying to set up a page with multiple galleries using CoolLightBox. It worked fine for me when I had just one gallery, but now that I want to create multiple galleries - each with its own image on the page - it is only displaying one image in the ligh ...

Exploring the FunctionDirective in Vue3

In Vue3 Type Declaration, there is a definition for the Directive, which looks like this: export declare type Directive<T = any, V = any> = ObjectDirective<T, V> | FunctionDirective<T, V>; Most people are familiar with the ObjectDirectiv ...

Sizing labels for responsive bar charts with chart.js

I'm encountering a problem with my bar chart created using chart.js - the responsive feature works well for some elements but not all. Specifically, the labels on my bar chart do not resize along with the window, resulting in a strange look at smaller ...

Is it possible to set a read-only attribute using getElementByName method

To make a text field "readonly" by placing JavaScript code inside an external JS file, the HTML page cannot be directly modified because it is located on a remote server. However, interaction can be done by adding code in an external JS file hosted on a pe ...

Enhance the functionality of the kendo grid by incorporating additional buttons or links that appear when the

Is there a method to incorporate links or buttons when hovering over a row in a kendo grid? I've searched through the documentation and looked online, but haven't found a solution. I'm considering if I should modify my row template to displa ...

The element is being offset by SVG animation that incorporates transform properties

I'm working on creating a halo effect by rotating an SVG circular element using the transform rotate function. I've been using getBox to find the center point of the element, but when the rotation occurs, the overall image is getting misaligned w ...

find the repeated sequences of characters within the text

Trying to grasp a javascript string variable source; Is there an efficient technique to identify all REPEATED substrings of length around 20 characters (even if they overlap or include substrings of slightly different lengths)? An approach that could be ...

Error encountered: JSHint is flagging issues with setting a background gradient using

I have been experimenting with animating a background gradient using jQuery, and here is the code snippet I am working with: this.$next.css('line-indent', 0).animate({ 'line-indent': 100 }, { "duration": 750, "step": functi ...

Uh-oh! An unexpected type error occurred. It seems that the property 'paginator' cannot be set

I am developing a responsive table using Angular Material. To guide me, I found this helpful example here. Here is the progress I have made so far: HTML <mat-form-field> <input matInput (keyup)="applyFilter($event.target.value)" placeholder ...

Struggling to incorporate pagination with axios in my code

As a newcomer to the world of REACT, I am currently delving into the realm of implementing pagination in my React project using axios. The API that I am utilizing (swapi.dev) boasts a total of 87 characters. Upon submitting a GET request with , only 10 cha ...

Generating and Importing Graphics through Iterations in Javascript

I apologize for my lack of experience in this matter. Can someone please guide me on how to utilize a loop to load images? For instance, could you show me how to rewrite the code below using a loop to automate the process? function loadImages() { let ...

What causes Three.js OBJ conversion to render as mesh successfully but log as undefined?

I'm just getting started with Three.js and I'm experimenting a lot. Although I'm new to Javascript as well, the issue I'm facing seems to be more about variable scoping and callback function protocols than it is about Three.js itself... ...

Tips for creating a new route within a separate component in React JS without causing the previous one to unmount

I am currently developing a recipe website using React JS and React Router. On the HomePage, I have set up a display of cards, each representing a preview of a recipe. Each card is enclosed within a <Link></link> tag. When one of these cards ...

Generating a dynamic sitemap with Next.js

I have been working on a project where I need to create a sitemap, and I am currently using next-sitemap for generation. However, I've encountered an issue with this method, as well as other solutions I've come across, because the sitemap is only ...

Executing a npm script (script.js) with custom arguments - a step-by-step guide

I'm considering creating a setup similar to lodash custom builds. Basically, I want to allow users to input a command like: lodash category=collection,function This would create a custom module with the specified category. I've been looking in ...