mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-02-16 14:39:37 +00:00
Added functions to retrieve associated parts of an element within twig labels
This fixes #1239
This commit is contained in:
parent
233c5e8550
commit
aed2652f1d
3 changed files with 60 additions and 13 deletions
|
|
@ -91,7 +91,7 @@ in [official documentation](https://twig.symfony.com/doc/3.x/).
|
|||
|
||||
Twig allows you for much more complex and dynamic label generation. You can use loops, conditions, and functions to create
|
||||
the label content and you can access almost all data Part-DB offers. The label templates are evaluated in a special sandboxed environment,
|
||||
where only certain operations are allowed. Only read access to entities is allowed. However as it circumvents Part-DB normal permission system,
|
||||
where only certain operations are allowed. Only read access to entities is allowed. However, as it circumvents Part-DB normal permission system,
|
||||
the twig mode is only available to users with the "Twig mode" permission.
|
||||
|
||||
The following variables are in injected into Twig and can be accessed using `{% raw %}{{ variable }}{% endraw %}` (
|
||||
|
|
@ -99,10 +99,10 @@ or `{% raw %}{{ variable.property }}{% endraw %}`):
|
|||
|
||||
| Variable name | Description |
|
||||
|--------------------------------------------|--------------------------------------------------------------------------------------|
|
||||
| `{% raw %}{{ element }}{% endraw %}` | The target element, selected in label dialog. |
|
||||
| `{% raw %}{{ element }}{% endraw %}` | The target element, selected in label dialog. |
|
||||
| `{% raw %}{{ user }}{% endraw %}` | The current logged in user. Null if you are not logged in |
|
||||
| `{% raw %}{{ install_title }}{% endraw %}` | The name of the current Part-DB instance (similar to [[INSTALL_NAME]] placeholder). |
|
||||
| `{% raw %}{{ page }}{% endraw %}` | The page number (the nth-element for which the label is generated |
|
||||
| `{% raw %}{{ page }}{% endraw %}` | The page number (the nth-element for which the label is generated ) |
|
||||
| `{% raw %}{{ last_page }}{% endraw %}` | The page number of the last element. Equals the number of all pages / element labels |
|
||||
| `{% raw %}{{ paper_width }}{% endraw %}` | The width of the label paper in mm |
|
||||
| `{% raw %}{{ paper_height }}{% endraw %}` | The height of the label paper in mm |
|
||||
|
|
@ -236,12 +236,16 @@ certain data:
|
|||
|
||||
#### Functions
|
||||
|
||||
| Function name | Description |
|
||||
|----------------------------------------------|-----------------------------------------------------------------------------------------------|
|
||||
| `placeholder(placeholder, element)` | Get the value of a placeholder of an element |
|
||||
| `entity_type(element)` | Get the type of an entity as string |
|
||||
| `entity_url(element, type)` | Get the URL to a specific entity type page (e.g. `info`, `edit`, etc.) |
|
||||
| `barcode_svg(content, type)` | Generate a barcode SVG from the content and type (e.g. `QRCODE`, `CODE128` etc.). A svg string is returned, which you need to data uri encode to inline it. |
|
||||
| Function name | Description |
|
||||
|------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `placeholder(placeholder, element)` | Get the value of a placeholder of an element |
|
||||
| `entity_type(element)` | Get the type of an entity as string |
|
||||
| `entity_url(element, type)` | Get the URL to a specific entity type page (e.g. `info`, `edit`, etc.) |
|
||||
| `barcode_svg(content, type)` | Generate a barcode SVG from the content and type (e.g. `QRCODE`, `CODE128` etc.). A svg string is returned, which you need to data uri encode to inline it. |
|
||||
| `associated_parts(element)` | Get the associated parts of an element like a storagelocation, footprint, etc. Only the directly associated parts are returned |
|
||||
| `associated_parts_r(element)` | Get the associated parts of an element like a storagelocation, footprint, etc. including all sub-entities recursively (e.g. sub-locations) |
|
||||
| `associated_parts_count(element)` | Get the count of associated parts of an element like a storagelocation, footprint, excluding sub-entities |
|
||||
| `associated_parts_count_r(element)` | Get the count of associated parts of an element like a storagelocation, footprint, including all sub-entities recursively (e.g. sub-locations) |
|
||||
|
||||
### Filters
|
||||
|
||||
|
|
@ -285,5 +289,5 @@ If you want to use a different (more beautiful) font, you can use the [custom fo
|
|||
feature.
|
||||
There is the [Noto](https://www.google.com/get/noto/) font family from Google, which supports a lot of languages and is
|
||||
available in different styles (regular, bold, italic, bold-italic).
|
||||
For example, you can use [Noto CJK](https://github.com/notofonts/noto-cjk) for more beautiful Chinese, Japanese,
|
||||
and Korean characters.
|
||||
For example, you can use [Noto CJK](https://github.com/notofonts/noto-cjk) for more beautiful Chinese, Japanese,
|
||||
and Korean characters.
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ final class SandboxedTwigFactory
|
|||
'barcode_svg',
|
||||
//SandboxedLabelExtension
|
||||
'placeholder',
|
||||
'associated_parts', 'associated_parts_count', 'associated_parts_r', 'associated_parts_count_r',
|
||||
];
|
||||
|
||||
private const ALLOWED_METHODS = [
|
||||
|
|
|
|||
|
|
@ -23,14 +23,18 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Twig\Sandbox;
|
||||
|
||||
use App\Entity\Base\AbstractPartsContainingDBElement;
|
||||
use App\Entity\Parts\Part;
|
||||
use App\Repository\AbstractPartsContainingRepository;
|
||||
use App\Services\LabelSystem\LabelTextReplacer;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
class SandboxedLabelExtension extends AbstractExtension
|
||||
{
|
||||
public function __construct(private readonly LabelTextReplacer $labelTextReplacer)
|
||||
public function __construct(private readonly LabelTextReplacer $labelTextReplacer, private readonly EntityManagerInterface $em)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -39,6 +43,11 @@ class SandboxedLabelExtension extends AbstractExtension
|
|||
{
|
||||
return [
|
||||
new TwigFunction('placeholder', fn(string $text, object $label_target) => $this->labelTextReplacer->handlePlaceholderOrReturnNull($text, $label_target)),
|
||||
|
||||
new TwigFunction("associated_parts", $this->associatedParts(...)),
|
||||
new TwigFunction("associated_parts_count", $this->associatedPartsCount(...)),
|
||||
new TwigFunction("associated_parts_r", $this->associatedPartsRecursive(...)),
|
||||
new TwigFunction("associated_parts_count_r", $this->associatedPartsCountRecursive(...)),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -48,4 +57,37 @@ class SandboxedLabelExtension extends AbstractExtension
|
|||
new TwigFilter('placeholders', fn(string $text, object $label_target) => $this->labelTextReplacer->replace($text, $label_target)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all parts associated with the given element.
|
||||
* @param AbstractPartsContainingDBElement $element
|
||||
* @return Part[]
|
||||
*/
|
||||
public function associatedParts(AbstractPartsContainingDBElement $element): array
|
||||
{
|
||||
/** @var AbstractPartsContainingRepository $repo */
|
||||
$repo = $this->em->getRepository($element::class);
|
||||
return $repo->getParts($element);
|
||||
}
|
||||
|
||||
public function associatedPartsCount(AbstractPartsContainingDBElement $element): int
|
||||
{
|
||||
/** @var AbstractPartsContainingRepository $repo */
|
||||
$repo = $this->em->getRepository($element::class);
|
||||
return $repo->getPartsCount($element);
|
||||
}
|
||||
|
||||
public function associatedPartsRecursive(AbstractPartsContainingDBElement $element): array
|
||||
{
|
||||
/** @var AbstractPartsContainingRepository $repo */
|
||||
$repo = $this->em->getRepository($element::class);
|
||||
return $repo->getPartsRecursive($element);
|
||||
}
|
||||
|
||||
public function associatedPartsCountRecursive(AbstractPartsContainingDBElement $element): int
|
||||
{
|
||||
/** @var AbstractPartsContainingRepository $repo */
|
||||
$repo = $this->em->getRepository($element::class);
|
||||
return $repo->getPartsCountRecursive($element);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue