PortLAB
PortLAB is the platform used at CNR-IFAC (Institute of Applied Physics «Nello Carrara») to build and manage scientific portals: a single engine, written in PHP with a PostgreSQL database, from which different websites arise — multilanguage, responsive and rich in interactive content — while sharing structure, style and tools.
What it is
PortLAB is a lightweight framework for building portals. Each page is defined by a small declarative configuration (in JSON) that sets its structure, languages, libraries and access levels, while the content lives in separate per-language files. This makes it possible to add pages and whole sites quickly, keeping visual and functional consistency and without touching the engine.
Project-based architecture and customisation
PortLAB is organised around a main site that acts as a shared base for all the secondary projects hosted on the platform. Each project has its own content and its own local customisations, but automatically inherits from the main site both the common code and the third-party libraries, shared only once and maintained centrally: no duplication and immediate updates for everyone. At the same time, each project can customise any element at any point, selectively and independently replacing the shared version with its own local one. The result is a layered architecture — local elements, common elements and shared libraries, freely combinable — that makes it possible to launch new portals quickly while keeping a tailored identity and look for each.
Beyond the common code and libraries, the services and tools offered by PortLAB (database management and viewing, schema diagram, user management, log inspection and more) can also be inherited by secondary projects through symbolic links to the main project: every new portal thus gets the full toolset with no duplication, while still being able to replace or extend any part locally.
Graphical interface (GUI)
The interface is made of standard Bootstrap-based elements — headers, navigation bars, menus, breadcrumbs, footers and modal dialogs: independent, reusable building blocks to be combined until the desired page structure is obtained, with visual consistency and full responsiveness.
Template
The template is the page model: it sets which interface elements to use and how to lay them out, including the type of menu (horizontal at the top or on the side) and the overall style. Each template is a predefined, reusable combination of components, called by a page with a simple reference; changing template changes the look and layout of the whole page without touching its content.
Page descriptor
Every page is declared by a small JSON file, and the declaration is not a formality: without that file the page does not exist for the platform and its address answers «not found». It is the first link in the access control chain. The descriptor says which template to use, who may open the page, what to load and in which order, and how the page presents itself in the menu.
{
"template": 1,
"profiles": [1],
"flags": { "menu_order": 3 },
"libs": {
"css": ["/css/common/table.css", "/css/local/diagram.css"],
"js": ["/js/libs/jquery-4.0.0.min.js"],
"js_end": ["/js/local/diagram_ui.js"]
}
}
- template — the page model described just above.
- profiles — the authorised profiles. An empty list means a public page, not an unreachable one: it is the only opening, and it has to be written on purpose.
- libs — stylesheets and scripts in the exact order in which they are to be loaded, with js before the page body and js_end after it.
- flags.hide_in_menu — the page stays reachable by address but does not appear in the menu.
- flags.menu_order — the page's place among the files of its folder: ascending number and, on a tie or with no number at all, ordering by name. The name always breaks the tie, so a wrong number moves one entry and does not rearrange the section. Its purpose is to keep the ordering out of file names, which are also addresses.
Everything else is not configuration but files recognised by their name: the page body, one per language; a dictionary for the strings of the Javascript interface; and, if needed, a server-side logic file. Adding a page therefore means creating files, not editing a central register — which is why the menu, the breadcrumb and the search engine find it on their own.
Users, access and navigation
Multi-profile user management
Each user can be assigned several authorization profiles. A resource is accessible when at least one of the user's profiles matches one of the profiles required by the resource; pages with no profiles remain public. The same rule uniformly governs access to pages and sections, menu entries, downloadable files and even the visibility of individual portions of a page: the same page can thus show different content to users with different profiles.
Reserved area
Public pages are clearly separated from the application code and from reserved content, kept in an area located outside the web root and therefore not reachable directly from the browser. Reserved documents are never exposed as static URLs: they are delivered exclusively by server-side procedures that, before sending, verify the user's identity and profiles.
Security and cryptography
Protections are cross-cutting: sessions secured with anti-CSRF tokens, session-id regeneration and cookies with security attributes (HttpOnly, Secure, SameSite); passwords kept only as hashes; query parameters validated and constrained. Reserved content and «capability» links are protected with standard cryptography (AES-256 with HMAC authentication) and keys kept outside the source code. Access control is fail-closed: a page is reachable only if explicitly configured, and even the server-side computation endpoints are subject to the user's profiles. Requests to non-existent resources are routed to standard error pages that lead back to the home page.
Dynamic generation of the navigation menu
The menu is not hand-written: it is built automatically by exploring the tree of folders and pages. Every new page appears on its own, organised on multiple levels according to nesting; entries are filtered by the user's profile and by a dedicated exclusion flag, and the titles are taken from the page in the chosen language. Files come before subfolders; among files the order is the number declared in the page descriptor, with the name breaking ties and standing in when no number is given. A section is therefore reordered by changing a number, with no file renamed and no address moved.
Content, search and privacy
Multilanguage support
The available languages are declared per page. The body of each page lives in a separate file for each language, while the interface strings are handled by a dictionary-based translation system that works identically in PHP and Javascript: the same function and the same dictionaries are available both on the server and in the browser. This makes it possible to translate on the fly any string, from any section of the page — including those produced by Python or C++ programs run through the gateway (gw2py) and returned to the page.
An extension for parametric strings is also available: the translated text
contains numbered placeholders (e.g. {0}, {1}) replaced at
runtime with the actual values. This is essential because in different languages the
parameter may take a different position in the sentence: the placeholder is
put where each translation needs it, so the text stays natural (for example
«{0} elementi trovati» in Italian becomes «found {0} items»
in English, with the value in different places). The whole pipeline is UTF-8, so any
alphabet can be hosted; the portals are currently in Italian and English, with a
flag-and-code language selector.
Built-in text search
By typing at least three characters, the system scans the site pages in the currently selected language and shows the results in a dedicated window. For each page an excerpt is presented with title, keywords, description and text in which the searched term appears, highlighted in its context, with a direct link to the page. The search correctly handles international alphabets and characters (UTF-8) and can be targeted, page by page, to the relevant paragraphs only.
GDPR management
PortLAB includes ready-to-use GDPR handling: a dedicated privacy/cookie notice and a consent banner reused by all sites. The platform is set up to use technical cookies only, with no profiling or third parties; the banner is purely informative, does not block navigation and remembers acknowledgement for a set period.
Database tools (PostgreSQL)
Table management
A single reusable interface makes it possible to create, edit, delete and browse the rows of the database tables, with multi-criteria filtering, customisable sorting, pagination and JSON import/export of the criteria.
Data viewing and exploration
A complete database viewer brings together four tools: a navigator that explores databases, schemas, tables, views, materialized views and functions through an interactive tree and cascading filters (showing structure, types, keys, sizes and definitions); an SQL query executor with an advanced editor, direct execution and CSV export of the results; a library of stored queries recallable with one click; and a keyword search across all fields, with filters by schema, table, field and data type.
Graphical schema diagram
A graphical viewer generates an interactive diagram of the schema: each table or view is a node listing its fields with the primary key highlighted. Nodes can be dragged freely on the work surface and the links between related fields are drawn as lines; layout, colours and links are saved and restored at every visit.
Administration and diagnostics
Server log inspection
An administration console makes it possible to inspect the Apache logs — accesses and errors — filtering the lines by inclusion or exclusion of a string, with the option to hide informational messages or to clear the log; a dedicated section shows the server's PHP configuration. Access is restricted to administrators.
Standardised error messages
Every critical point in the code — SQL queries, PHP operations, calls to the Python gateway, client-side scripts — is marked with a code/index: when something goes wrong a uniform message reports that code, making it possible to pinpoint exactly where the problem occurred. Messages are tailored to the profile: a regular user sees an essential notice with the code, while the administrator is also shown the technical details (type, file, line, query text) useful for debugging. The mechanism is uniform for both pages and AJAX calls.
Technology
At the heart of the server side is a gateway that lets pages invoke, in a uniform way, programs and computations written in different languages — so far Python and C++ — returning the results (usually as JSON) directly into the page. The gateway is used pervasively together with jQuery's AJAX interface: this has effectively standardised the calls across the whole portal, with a single request/response scheme for any dynamic operation.
- Engine in PHP on Apache/Linux, PostgreSQL database; front-end on Bootstrap 5 and jQuery.
- Pages configured declaratively (JSON): template, metadata, libraries and access profiles, without changing the engine.
- Reusable components and server-side computation via a Python gateway: pages can launch simulations and processing and display the results.
- Interactive scientific content: charts (ECharts), LaTeX formulas (KaTeX), 3D visualizations (three.js), syntax-highlighted code.
- A wizard to start new portals; responsive layout for desktop and mobile.
Projects built with PortLAB
- WebNIR — CNR-IFAC portal on non-ionizing radiation: electromagnetic fields (EMF), artificial optical radiation (AOR) and active implantable medical devices, with tools for exposure and shielding assessment.
- UISH — Urban Intelligence Science Hub — a CNR project for the digital twin of the city: CNR-IFAC's activity on air quality in Catania and the validation of the AirPortal model.
- Purple — a portal dedicated to analytical methods and to the archive of environmental activities and measurements.
- Administration console — the management interface of the platform itself, which also hosts an educational section with interactive examples (the Quantum Monte Carlo suite for the Schrödinger equation and the Pythagorean theorem).
Keywords: PortLAB, CMS, PHP framework, scientific portals, multilanguage, PostgreSQL, CNR-IFAC