PortLab

Management of web portals dedicated to research projects

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.

PortLAB layered architecture The main site shares common code, third-party libraries and services with the secondary projects, which add local content and customisations. Project A Local content Customisations Project B Local content Customisations Project C Local content Customisations inherits via symbolic links MAIN SITE — shared base Common code Third-party libraries Services and tools
Layered architecture: a shared base from the main site, customisable locally by each project.
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.

Anatomy of a page The template combines the interface building blocks: header, navigation bar with menu, breadcrumb, body with an optional side menu, and footer. Header Navbar + menu Breadcrumb Side menu(optional) Page body Footer
The template selects and combines the interface building blocks (GUI) to form the page.
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"]
  }
}

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.

Technology stack The browser talks over HTTP/AJAX to the Apache/PHP server, which queries the PostgreSQL database and delegates computation to a gateway that runs programs in different languages. Browser Bootstrap · jQuery ECharts · KaTeXthree.js · highlight Server Apache + PHP PortLAB engine Profiles · session PostgreSQL Data · usersschemas, tables, views Gateway (gw2py) compute: Python, C++ HTTP / AJAXSQL
From browser to database: the PHP engine orchestrates data and computation; the gateway runs programs in several languages.

Projects built with PortLAB

Keywords: PortLAB, CMS, PHP framework, scientific portals, multilanguage, PostgreSQL, CNR-IFAC

Moreno Comelli, CNR-IFAC, 2022-2026