Base code - This will get you every role associated to every /task/ on the project, inactive or otherwise. That is not the same as every role associated to the /people/ assigned to things on the project.
displayname=Nested Roles
listdelimiter=<p>
listmethod=nested(roles).lists
type=iterate
valueexpression={name}
valuefield=name
valueformat=HTML
This code will get you every role associated to every person assigned to something on the project:
displayname=Nested Roles
listdelimiter=<p>
listmethod=nested(projectUserRoles).lists
type=iterate
valueexpression={role}.{name}
valuefield=name
valueformat=HTML
If you want to see that with the user's name as well, this will do that.
displayname=Project Users
listdelimiter=<br>
listmethod=nested(projectUsers).lists
type=iterate
usewidths=true
valueexpression=CONCAT({user}.{name}," - ",{user}.{role}.{name})
valueformat=HTML
width=200
To drop inactive records, this is a sample based on the first list, but would work the same on the rest too.
displayname=Nested Roles
listdelimiter=<p>
listmethod=nested(roles).lists
type=iterate
valueexpression=IF({isActive},{name},"")
valuefield=name
valueformat=HTML
As a side note, if you have 3 people with a particular role associated to a project, that role will be listed 3 times in the output. There is no way I have ever found to de-duplicate that info.
One common point of confusion is that the 'Project Users' will sometimes contain people who have long-since left the project and are no longer assigned to anything. That is accurate info based on standard Workfront functionality. The 'User' data is a complete historical record, even when business logic would consider it 'wrong'. The only way to fix that information is to use Fusion in a really complicated cleanup scenario.