Q:

Angular 6+. How to extend a template adding new actions such as JSF?

I'm trying to implement the concept of pages composition from JSF in Angular6 + but I have no idea how to start it. Here is what I need:
1) A template page such as search page where there are placeholders for fields, search action and search results table.
2) A page that extends template and add its fields, action and results
3) Possibility to extend # 2 and add custom actions to results data table rows.
Following picture describes each item above:
1) Search page general template

2) Custom search page (extends #1)

3) Custom action added to search page (extends #2)

3.1) Similar page to #3 but it has different action on result row (extends #2)

I want to is to standardize all the pages based on few base templates (# 1) and reuse specific pages adding new actions to it (#2). As the result, # 3 will be shown the final user and it may be used in different places with minor changes, for instance, I can search for the employee and open it OR I can lookup employee using this same search page but instead of opening its record, I will select it to fill a field from other form. In this example, all I need to do is the extend #2 and add specific action that will open or just lookup employee and set to other form.
PS: Developer may add component in placeholders.
Updates:
22/11/2018
Based on advice from Bunyamin Coskuner, I implemented a sample pretty quickly but now I'm stuck on a specific behavior.
I created a StackBlitz project and published my sample code:
https://stackblitz.com/edit/angular-s2wkpw
Just click on "search" and take a look at the results. Action buttons are added only in last row. What is the best way to replicate these buttons in every row?
PS: Each button must pass correct parameter based on what is in the row to controller.
I would like to ask the Angular experts if is this the best approach to archieve what I'm trying to.

Thanks in advance.

A:

You came pretty close, I just added a directive to solve the rest. Here is the final stackblitz
<ng-content select="...> works on static content projection. Sometimes, you need more powerful directive than that.
There is a little trick I got it from Angular Material codebase and use it in almost all of my components which is providing customizable templates. 
Instead of writing <ng-content select="button"> which overrides other rows of the table and only put the buttons on the last one, you declare a directive as follows
@Directive({ selector: '[appPersonSearchButtons]' })
export class TemplatePersonSearchButtonsDirective {
    constructor(public template: TemplateRef<any>) { }
}

This directive may not look like it is doing much and I assure you it is!
It has single property which is template. It is injected here because we will use this directive with ng-template only! If you use this directive on any other element than ng-template you will get an error!
You should put this directive into declarations array of your module
declarations: [ ... TemplatePersonSearchButtonsDirective ... ]

Now, it is time to change <ng-content select="button"> to something else.
First, let's make sure whether consumers of this component used this directive within their template.
I added this line to TemplatePersonSearchComponent
@ContentChild(TemplatePersonSearchButtonsDirective) buttons: TemplatePersonSearchButtonsDirective;

I've changed <tr *ngFor...> to following 
<tr *ngFor="let person of persons; let i = index">
  <td width="80%">{{person}}</td>
  <td>
    <ng-container *ngIf="buttons">
      <ng-container *ngTemplateOutlet="buttons.template;
        context: { $implicit: person, index: i}">
      </ng-container>
    </ng-container>
  </td>
</tr>

ngTemplateOutlet is a directive that takes a TemplateRef as an input (which comes from buttons.template in this case). Also, you can pass a context too so that you can expose some data to the users (which will come in handy later). 
Let's use it in our employee-search-component. It is pretty much the same as you wrote it, I just moved buttons inside of an ng-template as follows
<app-template-person-search>
  <ng-template appPersonSearchButtons let-personObj let-id="index">
    <button (click)="openPerson(personObj, id)">Open</button>
    <button (click)="deletePerson(personObj, id)">Delete</button>
  </ng-template>
</app-template-person-search>

Remember, we defined our context as context: { $implicit: person, index: i}"
Since, we defined person as $implicit, you can write anything starting with let- to retrieve that object. I chose personObj to show that you can type anything. Also, I retrieved index as id and pass these objects into a function.
openPerson(person, id) {
    alert('Open ' + person + ' ' + id);
}

deletePerson(person, id) {
    alert('Delete ' + person + ' ' + id);
}

