Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions classes/core/PKPBladeViewServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php

namespace PKP\core;

use PKP\core\PKPContainer;
use Illuminate\View\Factory as ViewFactory;
use Illuminate\View\FileViewFinder;
use Illuminate\View\DynamicComponent;
use Illuminate\View\ViewServiceProvider;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\Compilers\BladeCompiler;

class PKPBladeViewServiceProvider extends ViewServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerViewFinder();
$this->registerBladeCompiler();
$this->registerEngineResolver();
$this->registerFactory();
}

/**
* Register the view environment.
*
* @return void
*/
public function registerFactory()
{
$this->app->singleton(
ViewFactory::class,
fn (PKPContainer $app) => $this->configureViewFactoryWithBindings($app)
);

$this->app->singleton(
'view',
fn (PKPContainer $app) => $app->get(ViewFactory::class)
);
}

/**
* Register the view finder implementation.
*
* @return void
*/
public function registerViewFinder()
{
$this->app->singleton(
'view.finder',
fn (PKPContainer $app) => new FileViewFinder(
$app->get('files'),
[
$app->basePath('/templates'),
$app->basePath('/lib/pkp/templates'),
]
)
);
}

/**
* Register the Blade compiler implementation.
*
* @return void
*/
public function registerBladeCompiler()
{
$this->app->singleton('blade.compiler', function (PKPContainer $app) {
return tap(new BladeCompiler(
$app->get('files'),
BASE_SYS_DIR . '/compiled',
$app->get('config')->get('view.relative_hash', false) ? $app->basePath() : '',
$app->get('config')->get('view.cache', true),
$app->get('config')->get('view.compiled_extension', 'php'),
), function (BladeCompiler $bladeCompiler) {
$bladeCompiler->component('dynamic-component', DynamicComponent::class);

// Register component namespaces for PKP and APP Blade components
$bladeCompiler->componentNamespace('PKP\\components', 'pkp');
$bladeCompiler->componentNamespace('APP\\components', 'app');

$this->app->instance(BladeCompiler::class, $bladeCompiler);
$this->app->alias(
BladeCompiler::class,
(new class extends \Illuminate\Support\Facades\Blade {
public static function getFacadeAccessor() { return parent::getFacadeAccessor(); }
})::getFacadeAccessor()
);
});
});
}

/**
* Register the Blade engine implementation.
*
* @param \Illuminate\View\Engines\EngineResolver $resolver
* @return void
*/
public function registerBladeEngine($resolver)
{
$resolver->register(
'blade',
fn () => new CompilerEngine(
$this->app['blade.compiler'],
$this->app['files']
)
);
}

/**
* Configure the view factory with required bindings and setting the alias
*
* @param \PKP\core\PKPContainer $app
* @return \Illuminate\View\Factory
*/
protected function configureViewFactoryWithBindings(PKPContainer $app): ViewFactory
{
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app->get('view.engine.resolver');

$finder = $app->get('view.finder');

$factory = $this->createFactory($resolver, $finder, $app->get('events'));

// We will also set the container instance on this view environment since the
// view composers may be classes registered in the container, which allows
// for great testable, flexible composers for the application developer.
$factory->setContainer($app);

$factory->share('app', $app);

$app->instance(\Illuminate\Contracts\View\Factory::class, $factory);
$app->alias(
\Illuminate\Contracts\View\Factory::class,
(new class extends \Illuminate\Support\Facades\View {
public static function getFacadeAccessor() { return parent::getFacadeAccessor(); }
})::getFacadeAccessor()
);

return $factory;
}
}
17 changes: 17 additions & 0 deletions classes/core/PKPContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use Illuminate\Support\Str;
use Laravel\Scout\EngineManager;
use PKP\config\Config;
use PKP\core\PKPBladeViewServiceProvider;
use PKP\i18n\LocaleServiceProvider;
use PKP\proxy\ProxyParser;
use Throwable;
Expand Down Expand Up @@ -57,6 +58,17 @@ public function __construct()
$this->registerCoreContainerAliases();
}

/**
* Get the application namespace.
* Required by Laravel's ComponentTagCompiler for component discovery.
*
* @return string
*/
public function getNamespace(): string
{
return 'PKP\\';
}

/**
* Get the proper database driver
*/
Expand All @@ -83,6 +95,7 @@ protected function registerBaseBindings(): void
static::setInstance($this);
$this->instance('app', $this);
$this->instance(Container::class, $this);
$this->instance(\Illuminate\Contracts\Foundation\Application::class, $this);
$this->instance('path', $this->basePath);
$this->instance('path.config', "{$this->basePath}/config"); // Necessary for Scout to let CLI happen
$this->singleton(ExceptionHandler::class, function () {
Expand Down Expand Up @@ -189,6 +202,7 @@ public function registerConfiguredProviders(): void
$this->register(new ConsoleCommandServiceProvider($this));
$this->register(new ValidationServiceProvider($this));
$this->register(new \Illuminate\Foundation\Providers\FormRequestServiceProvider($this));
$this->register(new PKPBladeViewServiceProvider($this));
$this->register(new \Laravel\Scout\ScoutServiceProvider($this));
}

Expand Down Expand Up @@ -336,6 +350,9 @@ public function registerCoreContainerAliases(): void
\Illuminate\Contracts\Encryption\Encrypter::class,
\Illuminate\Contracts\Encryption\StringEncrypter::class,
],
'view' => [
\Illuminate\Support\Facades\View::class,
],
] as $key => $aliases) {
foreach ($aliases as $alias) {
$this->alias($key, $alias);
Expand Down
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
"APP\\pages\\": "../../pages/",
"PKP\\": "classes/",
"APP\\": "../../classes/",
"PKP\\components\\": ["templates/components/"],
"APP\\components\\": ["../../templates/components/"],
"PKP\\plugins\\": "plugins/",
"APP\\plugins\\": "../../plugins/",
"PKP\\jobs\\": "jobs/",
Expand Down
20 changes: 17 additions & 3 deletions pages/about/AboutContextHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
use PKP\context\Context;
use PKP\facades\Locale;
use PKP\orcid\OrcidManager;
use Illuminate\Support\Facades\View;
use PKP\core\PKPContainer;
use PKP\plugins\Hook;
use PKP\security\authorization\ContextRequiredPolicy;
use PKP\security\Role;
Expand Down Expand Up @@ -57,9 +59,21 @@ public function authorize($request, &$args, $roleAssignments)
*/
public function index($args, $request)
{
$templateMgr = TemplateManager::getManager($request);
$this->setupTemplate($request);
$templateMgr->display('frontend/pages/about.tpl');
// Render template with page.blade.php
// we can also use View::make('TEMPLATE', [...]);
echo view('bladeTest.about', [
'title' => 'My Title',
'text' => 'This is my text!',
]);

// echo \Illuminate\Support\Facades\View::make('about', [
// 'title' => 'My Title',
// 'text' => 'This is my text!',
// ]);

// $templateMgr = TemplateManager::getManager($request);
// $this->setupTemplate($request);
// $templateMgr->display('frontend/pages/about.tpl');
}


Expand Down
6 changes: 6 additions & 0 deletions templates/bladeTest/about.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Hello World -- from /lib/pkp/template
params :
title : {{$title}}
text : {{$text}}

<x-hello-world></x-hello-world>
30 changes: 30 additions & 0 deletions templates/bladeTest/article.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

<x-authors :publication="$publication">
<x-authors.heading />
@foreach($component->authors as $author)
<x-author :author="$author">
<x-author.full-name />
<x-author.affiliations>
@foreach($component->affiliations as $affiliation)
<x-author.affiliation :affiliation="$affiliation">
<x-author.affiliation.name />
<x-author.affiliation.ror />
</x-author.affiliation>
@endforeach
</x-author.affiliations>
<x-author.user-group />
<x-author.orcid>
<x-author.orcid.icon />
<x-author.orcid.value />
</x-author.orcid>
<x-author.credit-roles>
@foreach($component->creditRoles as $creditRole)
<x-author.credit-role :credit-role="$creditRole">
<x-author.credit-role.name :credit-role="$creditRole" />
<x-author.credit-role.degree />
</x-author.credit-role>
@endforeach
</x-author.credit-roles>
</x-author>
@endforeach
</x-authors>
56 changes: 56 additions & 0 deletions templates/components/Author.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace PKP\components;

use Illuminate\View\Component;

class Author extends Component
{
/**
* The author object
*
* @var mixed
*/
public $author;

/**
* The author's affiliations
*
* @var array
*/
public $affiliations = [];

/**
* The author's credit roles
*
* @var array
*/
public $creditRoles = [];

/**
* Create a new component instance.
*
* @param mixed $author
*/
public function __construct($author = null)
{
$this->author = $author;

// Get affiliations and credit roles from author object
if ($author) {
$this->affiliations = $author->affiliations ?? [];
$this->creditRoles = $author->creditRoles ?? [];
}
}

/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|\Closure|string
*/
public function render()
{
// The component instance is available as $component in the view
return view('components.author')->with('component', $this);
}
}
51 changes: 51 additions & 0 deletions templates/components/Authors.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace PKP\components;

use Illuminate\View\Component;

class Authors extends Component
{
/**
* The publication object
*
* @var mixed
*/
public $publication;

/**
* The authors collection
*
* @var array
*/
public $authors = [];

/**
* Create a new component instance.
*
* @param mixed $publication
*/
public function __construct($publication = null)
{
error_log('AUTHORS CLASS');
$this->publication = $publication;

// Get authors from publication's authors field
if ($publication && isset($publication->authors)) {
$this->authors = $publication->authors;
} else {
$this->authors = [];
}
}

/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|\Closure|string
*/
public function render()
{
// The component instance is available as $component in the view
return view('components.authors')->with('component', $this);
}
}
Loading