1.0.0-Beta9
August 9, 2024
Last updated
Was this helpful?
August 9, 2024
Last updated
Was this helpful?
BoxLang Betas are released weekly. This is our ninth marker and we are incredibly excited as we are coming close to our stable release. We have some great news in this release!
PDFs have landed for BoxLang. The full implementation for creating PDF documents is now complete and available via our bx-pdf
module. This module contributes the following Components to the language:
document
- the wrapping component for creating PDF documents
The following attributes are available to the document
component
format
- The format of the document to generate. This attribute is unused and will be removed in a future release as only PDF generation is supported. Any other format requested will throw an error.
encryption
- The encryption level to use for the document. Default is none. Possible values are 128-bit, 40-bit, none
localUrl
- If true, the document will be generated with local URLs. Default is false
variable
- The name of the variable to store the generated PDF binary
backgroundVisible
- If true, the background will be visible. Default is true
bookmark
- If true, bookmarks will be generated. Default is true
htmlBookmark
- If true, it is possible to convert outlines to a list of named anchors (<a name="anchor_id">label</a>
) or a headings structure ( <h1>... <h6>
). Transforming of HTML hyperlinks to PDF hyperlinks (if not explicitly disabled Hyperlink jumps within the same document are supported as well
orientation
- The orientation of the document. Default is portrait. Possible values are portrait, landscape
scale
- The percentage to scale the document. Must be less than 100
marginBottom
- The bottom margin of the document
marginLeft
- The left margin of the document
marginRight
- The right margin of the document
marginTop
- The top margin of the document
pageWidth
- The width of the page in inches
pageHeight
- The height of the page in inches
fontEmbed
- If true, fonts will be embedded in the document. Default is true
fontDirectory
- The directory where fonts are located
openpassword
- The password to open protected documents
ownerPassword
- The password to access restricted permissions
pageType
- The type of page to generate. Default is A4.
pdfa
- If true, the document will be generated as a PDF/A document. Default is false
filename
- The filename to write the PDF to. If not provided and a variable
argument is not provided, the PDF will be written to the browser ( Web-context only )
overwrite
- If true, the file will be overwritten if it exists. Default is false
saveAsName
- The name to save the PDF as in the browser
src
- A full URL or path relative to the web root of the source
srcfile
- The absolute path to a source file
mimeType
- The mime type of the source. Default is text/html. Possible values are text/html, text/plain, application/xml, image/jpeg, image/png, image/bmp, image/gif
unit
- The unit of measurement to use. Default is inches. Possible values are in, cm
The following attributes are not currently implemented and will throw an error if used
permissions
- Granular permissability is not yet supported
permissionspassword
- Granular permissability is not yet supported
userPassword
- Granular permissability is not yet supported
authPassword
- Granular permissability is not yet supported
authUser
- Granular permissability is not yet supported
userAgent
- HTTP user agent identifier
proxyHost
- IP address or server name for proxy host
proxyPassword
- password for the proxy host
proxyPort
- port of the proxy host
proxyUser
- user name for the proxy host
tagged
- yes|no ACF OpenOffice integration not supported
formfields
- yes|no Form field attributes are not implemented in standard module
formsType
- FDF|PDF|HTML|XML Form field attributes are not implemented in standard module
documentitem
- specifies header, footer, and pagebreaks within a document body or documentsection
The following attributes are available to the documentitem
component
type
A string which dictates the type of item. Accepted values are pagebreak
|header
|footer
evalAtPrint
This attribute is deprecated as all content is evaluated when the body of the tag is processed
documentsection
- Divides a PDF document into sections. Used in conjunction with a documentitem
component, each section can have unique headers, footers, and page numbers. A page break will always precede a section
The following attributes are available to the documentsection
component
marginBottom
- The bottom margin of the section in the unit specified in the document
component.
marginLeft
- The left margin of the section in the unit specified in the document
component.
marginRight
- The right margin of the section in the unit specified in the document
component.
marginTop
- The top margin of the section in the unit specified in the document
component.
mimeType
- The mime type of the content. If the content is a file, the mime type is determined by the file extension. If the content is a URL, the mime type is determined by the HTTP response.
name
- The name of the section. This is used as a bookmark for the section.
srcfile
- The absolute path of the file to include in the section.
src
- The URL or path relative to the web root of the content to include in the section.
The following attributes are not currently implemented and will throw an error if used
userAgent
- The HTTP user agent identifier to use when fetching the content from a URL.
authPassword
- The authentication password to use when fetching the content from a URL.
authUser
- The authentication user name to use when fetching the content from a URL.
Simple example using tag-based syntax to generate a physical file:
Example using script syntax to create a variable containing the binary contents of the PDF, which is then written to a file
This is a really step forward for BoxLang in providing the ability to serialize and deserialize any BoxLang type and any BoxLang class to binary recursively n-levels deep. We have introduced two BIFS to accomplish this:
objectSerialize( object, [filepath] ) : binary
objectDeserialize( input ) : object
You can pass ANY object
to the serialize function and it will recursively try to serialize the object to binary data. You can then store that in a database, cluster, cache, or a file using the filepath
argument. To deserialize you can use the objectDeserialize()
function and you can pass in the direct binary or a file path location for the binary.
The only requirement is that the object
be a BoxLang type or any Java type that implements serializable.
Also note that for CFML compatibility, the compat module will expose them as objectLoad()
and objectSave()
.
You can now exit the BoxLang REPL by typing quit
or exit
.
This was related to BL-110 but specifically to BoxLang classes. This allows us now to be able to take the state of any BoxLang class and be able to serialize it to binary. You can then deserialize the binary and inflate it back to a BoxLang object graph again.
The boxlang.json
get's a new top level configuration key: experimental
which will be a feature flags approach to turn on/off experimental features in BoxLang.
We have consolidated our CLI tooling to all funnel through the boxlang
binary script or boxlang.bat
for windows. You can now execute our CLI tools via action commands which is based on the following keys:
compile
- Executes the BoxLang compiler tool
cftranspile
- Executes the CF to BoxLang transpile tool
featureAudit
- Executes the feature audit tool
The BoxLang Cache BIFs have been renamed to be standardized to the following:
cache( [provider:default] )
cacheFilter()
cacheNames()
cacheProviders()
cacheService()
This introduces BigDecimal
usage all over BoxLang for two main use cases:
Being able to store and process very large numbers that wouldn't fit inside a Long
or a Double
like 111111111111111111111111111 + 222222222222222222222222222
Being able to retain precision for decimals-- even small ones. For ex: (0.1 + 0.2).toString()
outputs 0.30000000000000004
in Lucee 5 and ACF 2023. But in Lucee 6 and BoxLang, it correctly returns .3
without any special work
Not ALL numbers are a BigDecimal
-- just the ones that need to be:
integer literals in your source code less than 11 chars will be a java Integer
integer literals in your source code less than 20 chars will be a java Long
All other integer literals in your source will be a java BigDecimal
All decimal literals in your source will be a java BigDecimal
Furthermore, we have added a new NumberCaster
which we should be using as our primary caster that returns an instance implementing the Number
interface in Java
any recognizable classes like int, long, double, big decimal, etc are just returned directly
Any strings which contain integers (no decimal or sci notation) follow the same rules above (integer for small ones, long for bigger ones, big decimal for really big ones)
Any strings with a decimal or sci notation will be made a BigDecimal
Basically, we return the "Smallest" data type we can without losing any precision. (An Integer is about 24 Bytes and a BigDecimal is about 64 Bytes so it seemed worth optimizing a bit)
The web runtimes now have file uploading capabiltiies finalized.
BigIntegers cause error: integer number too large
Not all unquoted tag attribute values are parsing