Selection of the export document type in the exporter view

I am trying to find a way to use radio buttons to create a selection of document types for the export (e.g. pdf, html,…) and then pass the selected value to the exporter. We use a custom exporter, based on the html exporter. At the moment I use the “template” param (because we use a fixed template). The code for this is:

<div class="custom-control custom-radio">
  <%= radio_button_tag :template, "pdf", true, :class => 'custom-control-input' %>
  <label class="custom-control-label" for="template_pdf"><%= "pdf" %></label>
</div>
<div class="custom-control custom-radio">
  <%= radio_button_tag :template, "html", false, :class => 'custom-control-input' %>
  <label class="custom-control-label" for="template_html"><%= "html" %></label>
</div>

and inside the exporter to get the value:

file_type = File.basename(export_options[:template])

But with v4.1.2 this workaround isn’t working anymore. The export controller check the template for validity. See dradis-ce/export_controller.rb at develop · dradis/dradis-ce · GitHub

any ideas?

Hey @fabian thanks for posting, and welcome to the forums!

Can you tell us a bit more about this part?

document types for the export (e.g. pdf, html,…)

Typically, different document formats are handled by different server endpoints. You can see an example of that in dradis-projects, where you have the option to export a project Template in XML format or a full project Package in Zip format:

Each endpoint would then inherit from Dradis::Plugins::Export::Base and define it’s own #export function.

The framework is smart enough to detect multi-endpoint plugins, and route the call to the right #export method, depending on the user selection.

Ah the “save and restore project info” export is a good hint!
About your question:
We have a relatively complex exporter, because we have implemented some parts differently than intended in Dradis. We don’t work with the methodology node, but only with nodes and subnodes, in which the single methodologies “live”, so we can mix assessment types in one report. There are different layouts for different assessment types and I’ve implemented a pretty cool retest feature, which needs another logic, etc…
Long story short: In the end either an html document or a pdf should be generated. To keep the whole thing in one exporter, I want to create this selection and the exporter can then do the rest.

I still think that two endpoints with two #export methods is the way to go, think of them as the entry point. Let’s call what you have to day RealExport, then you can trick the framework with:

HTMLExport
  def export
    RealExport.export(format: html)
  end
end

And

PDFExport
  def export
    RealExport.export(format: :pdf)
  end
end

That way you keep your report-generating logic centralised, and still use the multi-endpoint and UI features of the framework to let user choose what they want to do.

Okay I forgot something to say: The exporter always generates a html. we use a converter script to generate a pdf from it, wich I call in the controller with a spawned process. So the whole decision process is inside the controller. like:

if type == pdf
file = html.to_pdf_with_fancy_converter_script
send_data file.read.bla
else
render html: html.html_safe

I understand what you mean but I’m just not sure if I can implement this here.

I think the same concept in my previous post applies, it’s only that the PDFExport#export method would do something like:

PDFExport
  def export
    file = HTMLExport.export()
    send_file file
  end
end

Something else, if you have the PDF in a file already, it’s more efficient to use send_file than send_data (watch out for path traversal though!).

I don’t quite understand how this works yet, but I’ll take a look at the code from the dradis-projects plugin. But basically I have two exporter files e.g. html.rb and pdf.rb. In html.rb the code is like before and pdf.rb calls html.export() and converts. Both are required in companyxyz_exporter.rb and each exporter gets a controller to either send_file (pdf) or render (html).

EDIT
Ahhh cool I have another idea. This should also make it possible to integrate an importer into the exporter? You could have a third option (html already exists): “convert from a html file to pdf”.
The exporter calls the importer, converts the html file and outputs the pdf.