Skip to content

Commit

Permalink
Merge pull request #55 from AthennaIO/develop
Browse files Browse the repository at this point in the history
chore(npm): update dependencies
  • Loading branch information
jlenon7 authored Jan 23, 2025
2 parents 2ac0620 + 2d07854 commit 61a2a70
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@athenna/view",
"version": "5.2.0",
"version": "5.3.0",
"description": "The Athenna template engine. Built on top of Edge.js.",
"license": "MIT",
"author": "João Lenon <[email protected]>",
Expand Down
12 changes: 12 additions & 0 deletions src/types/TagContract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* @athenna/view
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import type { TagContract as EdgeTagContract } from 'edge.js/types'

export type TagContract = Omit<EdgeTagContract, 'tagName'>
10 changes: 10 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @athenna/view
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

export * from '#src/types/TagContract'
54 changes: 52 additions & 2 deletions src/views/ViewImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@ import { Edge } from 'edge.js'
import { debug } from '#src/debug'
import { Config } from '@athenna/config'
import { resolve, isAbsolute } from 'node:path'
import { Is, File, Path } from '@athenna/common'
import type { TagContract } from '#src/types/TagContract'
import { Is, File, Path, Macroable } from '@athenna/common'
import { EmptyComponentException } from '#src/exceptions/EmptyComponentException'
import { NotFoundComponentException } from '#src/exceptions/NotFoundComponentException'
import { AlreadyExistComponentException } from '#src/exceptions/AlreadyExistComponentException'

export class ViewImpl {
export class ViewImpl extends Macroable {
/**
* Edge instance that is handling all the views.
*/
public edge: Edge

public constructor() {
super()
this.edge = Edge.create(Config.get('view.edge', {}))
}

Expand Down Expand Up @@ -152,6 +154,54 @@ export class ViewImpl {
return this
}

/**
* Add a new tag to templates. Just like @component
* @if, etc.
*
* @example
* ```ts
* import type { TagContract } from '@athenna/view'
*
* const reverseTagOptions: TagContract = {
* block: false,
* seekable: true,
* compile(parser, buffer, token) {
* buffer.outputRaw('Hello from reverse tag')
* }
* }
*
* View.addTag('reverse', reverseTagOptions)
*
* const output = await View.renderRaw('@reverse()') // 'Hello from reverse tag'
* ```
*/
public addTag(name: string, options: TagContract) {
this.edge.registerTag({ tagName: name, ...options })

return this
}

/**
* Remove some tag from views registered using
* "addTag" method.
*
* @example
* ```ts
* View
* .addTag('reverse', { ... })
* .removeTag('reverse')
* ```
*/
public removeTag(name: string) {
if (!this.edge.tags[name]) {
return this
}

delete this.edge.tags[name]

return this
}

/**
* Create a new view disk. View disks can be used
* to register multiple views at the same time.
Expand Down
66 changes: 66 additions & 0 deletions tests/unit/views/ViewImplTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,72 @@ export default class ViewImplTest {
}
}

@Test()
public async shouldBeAbleToAddTagsToBeUsedByAllViews({ assert }: Context) {
View.addTag('reverse', {
block: false,
seekable: true,
compile(_, buffer) {
buffer.outputRaw('Hello from reverse tag')
}
})

const content = await View.renderRaw('@reverse()')

assert.deepEqual(content, 'Hello from reverse tag')
}

@Test()
public async shouldBeAbleToRemoveGlobalTags({ assert }: Context) {
View.addTag('reverse', {
block: false,
seekable: true,
compile(_, buffer) {
buffer.outputRaw('Hello from reverse tag')
}
})

{
const content = await View.renderRaw('@reverse()')

assert.deepEqual(content, 'Hello from reverse tag')
}

View.removeTag('reverse')

{
const content = await View.renderRaw('@reverse()')

assert.deepEqual(content, '@reverse()')
}
}

@Test()
public async shouldBeAbleToRemoveGlobalTagsThatDoesNotExist({ assert }: Context) {
View.addTag('reverse', {
block: false,
seekable: true,
compile(_, buffer) {
buffer.outputRaw('Hello from reverse tag')
}
})

{
const content = await View.renderRaw('@reverse()')

assert.deepEqual(content, 'Hello from reverse tag')
}

View.removeTag('reverse')
View.removeTag('not-found')

{
const content = await View.renderRaw('@reverse()')

assert.deepEqual(content, '@reverse()')
}
}

@Test()
public async shouldBeAbleToCreateViewDisks({ assert }: Context) {
View.createViewDisk('test', Path.fixtures('views/admin'))
Expand Down

0 comments on commit 61a2a70

Please sign in to comment.