Cardshifter / HTML-Client

HTML/CSS/JS-based client for Cardshifter
http://cardshifter.zomis.net
Apache License 2.0
13 stars 5 forks source link

Different HTML files for different mods #88

Open Zomis opened 9 years ago

Zomis commented 9 years ago

related to #82, #67 and #68, it should be possible to use different HTML templates for different mods.

The HTML template could make use of several to-be-implemented AngularJS directives

I imagine a HTML file for a mod to be something like this: (just as an example, not saying that it will definitely end up like this, not even sure if all these things are possible)

<div class="game game-{{modName}}">
    <!-- Player display -->
    <div>
        <player who="user">
            <properties>
                <property value="HEALTH" />
                <property value="MAX_HEALTH" />
                <property value="MANA" />
                <property value="MAX_MANA" />
            </properties>
            <zone which="hand" />
            <zone which="battlefield" />
            <zone-count which="deck" /> <!-- only shows number of cards -->
            <actions />
        </player>
        <player who="opponent">
            <properties>

            </properties>
            <actions />
            <zone-count which="hand" /> <!-- only shows number of cards -->
            <zone-count which="deck" /> <!-- only shows number of cards -->
        </player>
    </div>
</div>
acostarelli commented 8 years ago

Is the HTML file an actual HTML file that will be rendered, or is it a configuration file?

Zomis commented 8 years ago

I'd say that it is sort of a template file. At least in Angular, as we're using quite a bit of {{card.properties.health}} or similar.

punmechanic commented 8 years ago

The only problem I see here is how Angular requires directives to be defined:

Now, you could create directives at runtime - but you definitely don't want to do this as it ends up being hard to reason about the application itself. The other option is to load templates at runtime and use them as a basis for your layout (but don't make them a directive). This is complicated and not easy

Webpack itself supports asynchronous loading of stuff just fine, however you have to remember that webpack is a bundler and it doesn't really expect to have to load anything "new" that it didn't know about at compile time. For example, if you know all of the layouts ahead of time, you can simply do:

// require.ensure ensures that any attempt to require() the given template will
// be able to be resolved synchronously
require.ensure('path/to/template.html', function(templatePath) {
  var template = require(templatePath)
})

If you don't know them ahead of time, then you need to have a way of specifying where to load them, but at this point webpack isn't going to be helping you as it isn't designed to manipulate run time assets - only assets at compile time.

Zomis commented 8 years ago

According to @danpantry: Angular can already do this using ng-bind-html and/or $templateRequest. See http://chat.stackexchange.com/transcript/message/26712542#26712542

acostarelli commented 8 years ago

I think I'm still confused about the idea. Is this a file that will, based on the directives it's using, end up equating to a new HTML file? Or, is this a file that should be changed into a, for example, JavaScript object with the file's data put into the object accordingly?

punmechanic commented 8 years ago

Given some more thought into this.

My main concern is simply security. You need some way of verifying the integrity of the HTML files that you're downloading and you also need to make sure that they are not doing anything malicious (script tags embedded in them would be bad for example).

I'm going to assume one of the main reasons for this would be styling, so you essentially need a way of downloading HTML files with styles but not rendering script tags. There doesn't seem to be an easy answer to this, so i'm just spitballing.

To that end, I don't think you'd want to be using raw HTML but probably a preprocessed version. One example might be Jade, though I'm not sure that works in the browser. You could ask for Jade files (or for gzipped bundles containing jade files and other assets) and compile them at runtime, but this leaves performance overhead on the user - not great.

Another option would be to have a central, authoritative registry of these templates. This would greatly help with the security - you could build them all ahead of time at runtime and its just the user that needs to download them, but I think this goes counter to what you want.

Again, just spitballing.

acostarelli commented 8 years ago

Regarding verifying the HTML files, perhaps there could be a server-side script to do this. For example, Python has Beautiful Soup which allows for easily reading HTML files. Maybe when the user loads the HTML files into the client, they can get sent to the server to be verified by the server using a Python + BS script.

However, I don't know much about security and this could potentially raise other problems if the user sends in files that aren't actually HTML files.

punmechanic commented 8 years ago

If you already have a server side script I would honestly just say you should have an authoritative server model. As you pointed out there are too many ifs and buts to consider.

Zomis commented 8 years ago

I think that we will go with an authorative server. At least for now. So security is not the biggest issue here.

punmechanic commented 8 years ago

Let's keep this in mind given the refactoring we're doing

acostarelli commented 8 years ago

A question about the snippet in the question: what if a user left out <zone which="battlefield" />? Would the game logic change?

acostarelli commented 8 years ago

Note: I think I'm still misunderstanding some things about how the mods and templates integrate, so some ideas in this may be farfetched.

About somehow getting the template file from the user, I don't know if using require would be the best idea because then only the user(s) "hosting" the client would be able to add templates, and that would have to be done by adding the template to a specific folder. Is this the intent? Or, should we allow any user using the client to be able to add a template (the template would be local on their client, I'd say, but they'd be able to allow others to play using their template).

If we go with the latter option, then we could try loading the template file through a <input type="file">.

punmechanic commented 8 years ago

Note that in order to do this we need to dangerously set inner html

Zomis commented 8 years ago

There's been some more discussions here recently:

http://chat.stackexchange.com/transcript/16134?m=30151742#30151742

The approach right now would be to store the HTML templates on the game server, and when the game starts a mod it sends a request to fetch all the templates relevant for that mod, then it stores those templates as a string. It setups the game using one of the templates, like game template. It then requests templates for zones, players, and cards and at runtime decides on which template to use for which zone/player/card.

Phrancis commented 8 years ago

@Zomis how would this affect the way we will (eventually) build the site with React?

Zomis commented 8 years ago

I don't know React enough to answer that at the moment.

Phrancis commented 6 years ago

We are using Vue.js now, and this would definitely be possible to load different templates both HTML and CSS for different mods. Let's discuss some ideas.

Zomis commented 6 years ago

Vue has the concept of dynamic components which I think would solve this issue: https://vuejs.org/v2/guide/components.html#Dynamic-Components