Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
com.mchange:unstatic_3
Advanced tools
Towards a static site generator generator (and dynamic sites too)
Unstatic means to be a static-site-generator generator (really a generator of generators of sites that can be static, semi-static, or dynamic).
We'll use a giter8 template.
Any giter8-compatible tool would work (g8
, mill init
, sbt new
).
% sbt new swaldman/unstatic-seed.g8
[info] welcome to sbt 1.8.2 (Oracle Corporation Java 17.0.5)
[info] loading settings for project global-plugins from dependency-graph.sbt,gpg.sbt,metals.sbt ...
[info] loading global plugins from /Users/swaldman/.sbt/1.0/plugins
[info] set current project to new (in build file:/private/var/folders/by/35mx6ty94jng67n4kh2ps9tc0000gn/T/sbt_898e9db1/new/)
name [Unstatic Example]: mysite.com
module [mysite.com]: mysite
package [example]: com.mysite
untemplate_version [0.0.4]:
mill_version [0.10.11]:
Template applied in /Users/swaldman/mysite.com
Start the development server:
% cd mysite.com
% ./mysite-site-devcycle.sh
Compiling /Users/swaldman/Dropbox/BaseFolders/development-why/gitproj/mysite.com/buildCompilationSettings.sc
Compiling /Users/swaldman/Dropbox/BaseFolders/development-why/gitproj/mysite.com/build.sc
[38/53] mysite.compile
[info] compiling 3 Scala sources to /Users/swaldman/Dropbox/BaseFolders/development-why/gitproj/mysite.com/out/mysite/compile.dest/classes ...
[info] done compiling
[53/53] mysite.runBackground
Watching for changes to 6 paths... (Enter to re-run, Ctrl-C to exit)
Endpoints to serve:
- GET / -> -/status code (301) {header Location: /index.html}
- GET /index.html -> {body as text/plain (UTF-8)}/{header Content-Type: text/html; charset=UTF-8} {body as text/html (UTF-8)}
- GET /* {header If-None-Match} {header If-Modified-Since} {header Range} {header Accept-Encoding} -> one of(status code (404)|status code (400)|status code (416))/one of(status code (304)|status code (206) {header Last-Modified} {header Content-Length} {header Content-Type} {header ETag} {header Accept-Ranges} {header Content-Range} {body as application/octet-stream}|status code (200) {header Last-Modified} {header Content-Length} {header Content-Type} {header ETag} {header Content-Encoding} {body as application/octet-stream})
Beginning HTTP Service on port 8999.
Then, open a browser on http://localhost:8999/
You should see a "Hello World!" site!
Run...
% ./mysite-site-gen.sh
[52/52] mysite.run
Endpoints generated:
➣ /index.html
Endpoints copied from static locations:
➣ / <- mysite/static
You will see a directory called public
appear in your directory.
That is your static site! Open a browser on a file URL to index.html
in that directory.
On a Mac...
% open public/index.html
You should see exactly the site you saw from the development server!
The default site definition is a Scala object, which you'll find at mysite/src/com/mysite/MysiteSite.scala
:
package com.mysite
import ... // imports removed for brevity
object MysiteSite extends ZTSite.SingleRootComposite( JPath.of("mysite/static") ):
// edit this to where your site will actually be served!
override val serverUrl : Abs = Abs("https://www.example.com/")
override val basePath : Rooted = Rooted.root
// customize this to what the layout you want requires!
case class MainLayoutInput( renderLocation : SiteLocation, mbTitle : Option[String], mainContentHtml : String )
// get rid of this -- modify it into something useful and/or include something like a SimpleBlog defined as a singleton object
object HelloWorldPage extends ZTEndpointBinding.Source:
val location = MysiteSite.location("/index.html")
val task = zio.ZIO.attempt {
layout_main_html( MainLayoutInput( location, Some("Hello"), "<h1>Hello World!</h1>" ) ).text
}
val endpointBindings = ZTEndpointBinding.publicReadOnlyHtml( location, task, None, immutable.Set("hello-world") ) :: Nil
end HelloWorldPage
// avoid conflicts, but early items in the lists take precedence over later items
override val endpointBindingSources : immutable.Seq[ZTEndpointBinding.Source] = immutable.Seq( HelloWorldPage )
object MysiteSiteGenerator extends ZTMain(MysiteSite, "mysite-site")
Each element of endpointBindingSources
defines a Seq
of pages that will be generated as endpointBindings
.
A factory method of ZTEndpointBinding.scala
specify the location, relative to site root (which need not be the server root, you can alter basePath
), a ZIO Task
that generates the contents.
Each binding gets a set of identifiers, which become IDs by which you can identify the endpoint (e.g. for links) if they are kept unique.
The HTML is generated by an untemplate, which is a text-file-ish shorthand for generating a top-level Scala function. Unlike most template libraries that try to be an abstraction above programming languages, an untemplate really is transparently just a specialized way to write Scala. You might see a lot of Scala in them!
The untemplate invoked to generate the default site is available as mysite/untemplate/com/mysite/layout-main.html.untemplate
.
Here are some things to try:
http://localhost:8999/
.
% ./mysite-site-devcycle.sh
Some("Hello")
to something elsemysite/untemplate/com/mysite/layout-main.html.untemplate
mysite/static/css/style.css
(which is linked in the untemplate in a way that self-relativizes from any location in the site)
After you make any change, you should be able to reload the page and see the changes.
(For the CSS, you may need to <shift>
-reload or whatever trick is necessary in your browser to skip the cache.)./mysite-site-devcycle.sh
, and look for compilation errors to correct!Coming soon!
(If you're impatient, check out the source for drafts.interfluidity.com
.)
FAQs
Towards a static site generator generator (and dynamic sites too)
We found that com.mchange:unstatic_3 demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.