In the application, run through the resultset in order, keep a stack of {level, closing_tag} pairs for those rows where closing_tag is not null. Whenever level is reduced from one row to the next (so level_current < level_previous), pop from the stack and insert into the result all pairs from the top of the stack where level >= level_current. At the end, pop and insert all the remaining stack elements (as if there were a last row with level=0).

It might be possible to express this in SQL with a clever recursive CTE query, but it'd be easier to implement this in application code; and would most likely work much faster.
--
Igor Tandetnik

Re: How do I combine these to 2 views ...

Use another CTE to bring all rows into the correct order.
Then a standard tree walk:

WITH RECURSIVE
data AS (
SELECT id, line, par, 0 AS close
FROM vtag
UNION ALL
SELECT id, line, par, 1
FROM vparent_closetag
ORDER BY id, close -- this relies on the ids being equal
),
t AS (
SELECT id, line, 0 AS lev, close
FROM data
WHERE par IS NULL