In the following minimal example, I have a template class in a namespace. The description of each member refers to another member.
/// #brief My namespace
namespace template_test
{
template <int param_v>
class TemplateClass
{
public:
/// #brief \ref template_test::TemplateClass::func2() <- OK
int func1() { return 1; }
/// #brief \ref func1() <- unable to resolve
int func2() { return 2; }
};
class InstanceClass
{
TemplateClass<5> m_templ_class;
};
} // namespace template_test
At this example, I get the error
unable to resolve reference to 'func1()' for \ref command
One possible solution would be to always reference to entire signature including the namespace template_test::TemplateClass::... like at func1(). But I find this quite confusing and if you change the namespace once, you have to refactor the entire documentation.
I am particularly surprised by the following observations:
It works without problems if the template class is in the main namespace.
template <int param_v>
class TemplateClass
{
public:
/// #brief \ref func2() <- OK
int func1() { return 1; }
/// #brief \ref func1() <- OK
int func2() { return 2; }
};
/// #brief My namespace
namespace template_test
{
class InstanceClass
{
TemplateClass<5> m_templ_class;
};
} // namespace template_test
It works without problems if no template is used.
/// #brief My namespace
namespace test
{
class NoTemplateClass
{
public:
/// #brief \ref func2() <- OK
int func1() { return 1; }
/// #brief \ref func1() <- OK
int func2() { return 2; }
};
class InstanceClass
{
NoTemplateClass m_no_templ_class;
};
} // namespace test
How does this particular behavior occur when a template class is inside a namespace?
Is there an easier way than specifying namespace and class name for each reference?
Regarding this posting, EXTRACT_ALL is set to YES.
ETA:
As soon as I remove the
class InstanceClass
{
TemplateClass<5> m_templ_class;
};
it's possible to create the links to both functions within the TemplateClass.
Difference with default Doxyfile
# Difference with default Doxyfile 1.9.5 (2f6875a5ca481a69a6f32650c77a667f87d25e88)
PROJECT_NAME = ${PROJECT_NAME}
OUTPUT_DIRECTORY = ${DOCS_OUTPUT_DIRECTORY}
STRIP_FROM_PATH = ${PROJECT_SOURCE_DIR}
TOC_INCLUDE_HEADINGS = 0
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
CASE_SENSE_NAMES = YES
SORT_MEMBER_DOCS = NO
WARN_AS_ERROR = YES
WARN_LOGFILE = ${DOXYGEN_WARN_LOG_FILE}
INPUT = ${INPUTS}
FILE_PATTERNS = ${FILE_PATTERNS}
RECURSIVE = YES
EXCLUDE_PATTERNS = *.txt
EXAMPLE_RECURSIVE = YES
HTML_OUTPUT = _doxygen
HTML_EXTRA_STYLESHEET = ${SOURCE_DIR}/tools/doxygen/doxygen-awesome.css
USE_MATHJAX = YES
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
MATHJAX_EXTENSIONS = TeX/AMSmath \
TeX/AMSsymbols
SEARCHENGINE = NO
GENERATE_LATEX = NO
LATEX_CMD_NAME = latex
XML_OUTPUT = _doxygen/xml
MACRO_EXPANSION = YES
PREDEFINED = TSM_USE_VFC_UNITS
DIRECTORY_GRAPH = NO
DOT_IMAGE_FORMAT = svg
INTERACTIVE_SVG = YES
DOTFILE_DIRS = .
PLANTUML_JAR_PATH = /usr/share/plantuml/plantuml.jar
DOT_GRAPH_MAX_NODES = 350
As Albert wrote in the comments, it works without warning/error with Doxygen version 1.9.6. In this respect, this is the actual solution to the problem.
Related
I would like to load a plugin dynamically according to some data. First I tried to do it with Typoscript, but after some research I figured out, that it is not possible to change the settings of the plugin (see old forum entry).
I need to change settings.simplepoll.uid according to the passed data:
This is the Typoscript I tried:
lib.loadSimplepoll = USER
lib.loadSimplepoll {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = Simplepoll
pluginName = Polllisting
vendorName = Pixelink
switchableControllerActions {
SimplePoll {
1 = list
}
}
settings < plugin.tx_simplepoll.settings
settings {
simplepoll {
uid.current = 1
}
}
}
The call in the template looks like that:
<f:cObject typoscriptObjectPath="lib.loadSimplepoll">{newsItem.simplepoll}</f:cObject>
After figuring out, that changing the settings is not possible, I tried a viewhelper:
<?php
namespace Vendor\Extension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class LoadSimplepollViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
{
/**
* #param int $uid Uid of poll
* #return string
*/
public function render($uid) {
$cObj = GeneralUtility::makeInstance('TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer');
$configurationManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$simplepollTs = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
'simplepoll',
'Polllisting'
);
$ttContentConfig = array(
'tables' => 'tt_content',
'source' => 1030,
'dontCheckPid' => 1
);
// returning this works perfectly!
// but I need to change the "settings.simplepoll.uid"
$data = $cObj->RECORDS($ttContentConfig);
$cObj->start($data, 'tx_simplepoll_domain_model_simplepoll');
$renderObjName = '<tt_content.list.20.simplepoll_polllisting';
$renderObjConf = $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['simplepoll_polllisting.'];
$renderObjConf['persistence']['storagePid'] = 394; // This does not work!
$renderObjConf['settings'] = $simplepollTs;
$renderObjConf['settings']['simplepoll']['uid'] = $uid;
return $cObj->cObjGetSingle($renderObjName, $renderObjConf);
}
}
The viehelper is called like this:
{vh:LoadSimplepoll(uid: '{newsItem.simplepoll}')}
Now I am able to change the uid of the poll with this line:
$renderObjConf['settings']['simplepoll']['uid'] = $uid;
My problem is now, that it loads the poll, but not the answers. I tracked this down to the fact, that the plugin somehow does not know the Record Storage Page anymore. The line $renderObjConf['persistence']['storagePid'] = 394; does not help.
How can I tell the plugin the Storage Pid?
Or is there another/better way to load a plugin with changing data?
Why shouldn't it be possible to modify settings.simplepoll.uid in typoscript?
because the extension simplepoll does not handle any stdWrap functionality to its typoscript settings.
Have a look into the code:
this special setting is used here:
$simplePoll = $this->simplePollRepository->findByUid($this->settings['simplepoll']['uid']);
no stdWrap, just plain usage.
compare it to ext:news:
before any settings is used it is processed. A dedicated join of typoscript settings with the settings in the plugin. And if necessary there is a stdWrap possible: here
$this->originalSettings = $originalSettings;
// Use stdWrap for given defined settings
if (isset($originalSettings['useStdWrap']) && !empty($originalSettings['useStdWrap'])) {
$typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
$typoScriptArray = $typoScriptService->convertPlainArrayToTypoScriptArray($originalSettings);
$stdWrapProperties = GeneralUtility::trimExplode(',', $originalSettings['useStdWrap'], true);
foreach ($stdWrapProperties as $key) {
if (is_array($typoScriptArray[$key . '.'])) {
$originalSettings[$key] = $this->configurationManager->getContentObject()->stdWrap(
$typoScriptArray[$key],
$typoScriptArray[$key . '.']
);
}
}
}
As you can see:
extbase does not support you with typoscript stdWrap functionality.
You (and every extension author) need to do it by hand. But that was so even before extbase.
In this way: as you can not configure your value you only can trick TYPO3 (and the plugin):
if you have a small number of uids you can have one variant for each uid
lib.loadSimplepoll123 < lib.loadSimplepoll
lib.loadSimplepoll123.settings.simplepoll.uid = 123
lib.loadSimplepoll234 < lib.loadSimplepoll
lib.loadSimplepoll234.settings.simplepoll.uid = 234
lib.loadSimplepoll345 < lib.loadSimplepoll
lib.loadSimplepoll345.settings.simplepoll.uid = 345
lib.loadSimplepoll456 < lib.loadSimplepoll
lib.loadSimplepoll456.settings.simplepoll.uid = 456
and call it like
<f:cObject typoscriptObjectPath="lib.loadSimplepoll{newsItem.simplepoll}" />
or you build a pull request implementing the stdWrap functionality and send it to the extension author.
Why shouldn't it be possible to modify settings.simplepoll.uid in typoscript?
you just need the correct construction to modify it.
For a single value you can use current, but use it properly. It is a stdWrap function which needs to be evaluated.
If there is no stdWrap evaluation by default it might work with a cObject of type TEXT
settings.simplepoll.uid.cObject = TEXT
settings.simplepoll.uid.cObject.current = 1
or to indicate a stdWrap you need to use stdWrap literally:
settings.simplepoll.uid.stdWrap.current = 1
another variant of data transfer are named parameters. Just build an associative array as data parameter and access the values individual:
fluid:
<f:cObject typoscriptObjectPath="lib.arraytest" data="{a:'abc',b:'xyz'}" >
inside text
</f:cObject>
and the typoscript:
lib.arraytest = COA
lib.arraytest {
10 = TEXT
10.field = a
10.wrap = /|/
20 = TEXT
20.field = b
20.wrap = \|\
}
which results in an output of /abc/\xyz\. Be aware: the inner text of the f:cobject tag will be lost as the data parameter has priority about inner children.
In the meantime I got the Viewhelpter to work:
Viewhelper:
<?php
namespace Vendor\Extension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class LoadSimplepollViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
{
/**
* #return void
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('simplepollUid', 'int', 'Uid of simplepoll', false);
}
/**
* #return string
*/
public function render()
{
$configurationManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$simplepollTs = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
'simplepoll',
'Polllisting');
$cObj = GeneralUtility::makeInstance('TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer');
$renderObjName = '<tt_content.list.20.simplepoll_polllisting';
$renderObjConf = $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['simplepoll_polllisting.'];
$renderObjConf['settings'] = $simplepollTs;
$renderObjConf['settings']['simplepoll']['uid'] = (int)$this->arguments['simplepollUid'];
return $cObj->cObjGetSingle($renderObjName, $renderObjConf);
}
}
Call the viewhelper in the template (don't forget to register the namespace):
{vh:LoadSimplepoll(simplepollUid: '{newsItem.ipgSimplepoll}')}
That's it.
I builded an extension that has a 'details' table that holds details with a title and a description that be included inline to another object. Right now new details are stored in the same pid as the object, but I'd like to change that.
this question was answered by Merec and in the comments he points to a solution (add the column "pid" to your model, this is the first the model looks at) but asked to formulate a separate question for it ...
I took his suggestion but could not get it to work, so here is the separate question, in addition I would like to know how to get a value from the configuration to be used as pid for this.
update: René Pflamm pointed out that I should underline that I'm trying to set this Pid for saving in the backend, not in the frontend ... I basically recognized this destinction later on
my constants.ts :
plugin.tx_myext {
persistence {
# cat=plugin.tx_myext/storage/a; type=string; label=Default storage PID
defaultStoragePid =
# cat=plugin.tx_myext/storage/a; type=string; label=Details storage PID
detailsStoragePid =
}
}
my setup.ts
plugin.tx_myext {
persistence {
storagePid = {$plugin.tx_myext.persistence.defaultStoragePid}
detailPid = {$plugin.tx_myext.persistence.detailsStoragePid}
}
}
I am not sure if I understood you correctly but you can tell extbase to look in multiple pids for your records and state for each record where it should be stored:
plugin.tx_myext {
persistence {
storagePid = {$plugin.tx_myext.persistence.defaultStoragePid},{$plugin.tx_myext.persistence.detailStoragePid}
classes {
Vendor\MyExt\Domain\Model\Detail {
newRecordStoragePid = {$plugin.tx_myext.persistence.detailStoragePid}
}
}
}
}
Models inherits from TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject which has getter and setter for $pid. If you set the field, all automation to set the field (i.e. newRecordStoragePid in typoscript) are not used.
With this, you can set all storage locations you want.
$myModel = $this->objectManager->create('Vendor\\Namespace\\Domain\\Model\\MyModel');
$myModel->setPid(4321);
Part from TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject:
/**
* #var int The id of the page the record is "stored".
*/
protected $pid;
/**
* Setter for the pid.
*
* #param int|NULL $pid
* #return void
*/
public function setPid($pid)
{
if ($pid === null) {
$this->pid = null;
} else {
$this->pid = (int)$pid;
}
}
/**
* Getter for the pid.
*
* #return int The pid or NULL if none set yet.
*/
public function getPid()
{
if ($this->pid === null) {
return null;
} else {
return (int)$this->pid;
}
}
You can, when create elements in your extension, say the model which pid should be use.
In your TS:
plugin.tx_myext.settings {
detailPid = {$plugin.tx_myext.persistence.detailsStoragePid}
}
In your code above it can look like:
public function createDetailsAction(Detail $detail) {
$detail->setPid($this->settings['detailPid']);
$this->detailRepository->add($detail);
}
Is is possible to configure Aldec Riviera-PRO simulator to break simulation on either $error or $warning SystemVerilog calls? If it is then how?
I don't think there's a specific config option for promoting $error or $warning to a breakpoint in Riviera-PRO, although it worth checking with their support. You do have a couple of options:
Replace $error with $fatal
Write a VPI module to overload the system tasks with custom C code
The second option would look something like this:
#include "vpi_user.h"
// System function overload on $warning and $error to stop sim
static int system_function_overload(char *userdata)
{
vpiHandle systfref, args_iter, argh;
struct t_vpi_value argval;
const char *msg = "*** NO MESSAGE PROVIDED ***";
// Obtain a handle to the argument list
systfref = vpi_handle(vpiSysTfCall, NULL);
args_iter = vpi_iterate(vpiArgument, systfref);
// Pull out the string passed in as the first argument
if (args_iter) {
argh = vpi_scan(args_iter);
argval.format = vpiStringVal;
vpi_get_value(argh, &argval);
vpi_free_object(args_iter);
msg = argval.value.str;
}
vpi_printf("BREAK sim from %s:%d with msg %s\n",
vpi_get_str(vpiFile, systfref),
vpi_get(vpiLineNo, systfref),
msg);
vpi_control(vpiStop);
return 0;
}
static void register_system_functions(void)
{
s_vpi_systf_data tfData = { vpiSysTask, vpiSysTask };
tfData.sizetf = NULL;
tfData.compiletf = system_function_compiletf;
tfData.calltf = system_function_overload;
tfData.user_data = NULL;
tfData.tfname = "$warning";
vpi_register_systf( &tfData );
tfData.tfname = "$error";
vpi_register_systf( &tfData );
}
void (*vlog_startup_routines[])(void) = {
register_system_functions,
0
};
Is it possible to set a page's templavoila template with typoscript?
I have solved it with:
includeLibs.lang = fileadmin/user_tvtest.php
page.1 = USER_INT
page.1.userFunc = user_tvtest->main
page.10 = USER_INT
page.10.userFunc = tx_templavoila_pi1->main_page
page.10.disableExplosivePreview = 1
and in fileadmin/user_tvtest.php:
class user_tvtest
{
function main($content, $conf)
{
if (is_mobile())
{
$GLOBALS['TSFE']->page['tx_templavoila_to'] = 7;
//$GLOBALS['TSFE']->page['tx_templavoila_ds'] = 7;
}
}
}
http://daschmi.de/templavoila-template-domainbezogen-umschalten-gleicher-seitenbaum/
Look how the page is configured by TemplaVoila:
page = PAGE
page.typeNum = 0
page.10 = USER
page.10.userFunc = tx_templavoila_pi1->main_page
page.shortcutIcon = {$faviconPath}
They call the main_page function of class tx_templavoila_pi1 via page.userFunc:
/**
* Main function for rendering of Page Templates of TemplaVoila
*
* #param string Standard content input. Ignore.
* #param array TypoScript array for the plugin.
* #return string HTML content for the Page Template elements.
*/
function main_page($content,$conf) {
$this->initVars($conf);
// Current page record which we MIGHT manipulate a little:
$pageRecord = $GLOBALS['TSFE']->page;
// Find DS and Template in root line IF there is no Data Structure set for the current page:
if (!$pageRecord['tx_templavoila_ds']) {
foreach($GLOBALS['TSFE']->tmpl->rootLine as $pRec) {
if ($pageRecord['uid'] != $pRec['uid']) {
if ($pRec['tx_templavoila_next_ds']) { // If there is a next-level DS:
$pageRecord['tx_templavoila_ds'] = $pRec['tx_templavoila_next_ds'];
$pageRecord['tx_templavoila_to'] = $pRec['tx_templavoila_next_to'];
} elseif ($pRec['tx_templavoila_ds']) { // Otherwise try the NORMAL DS:
$pageRecord['tx_templavoila_ds'] = $pRec['tx_templavoila_ds'];
$pageRecord['tx_templavoila_to'] = $pRec['tx_templavoila_to'];
}
} else break;
}
}
// "Show content from this page instead" support. Note: using current DS/TO!
if ($pageRecord['content_from_pid']) {
$ds = $pageRecord['tx_templavoila_ds'];
$to = $pageRecord['tx_templavoila_to'];
$pageRecord = $GLOBALS['TSFE']->sys_page->getPage($pageRecord['content_from_pid']);
$pageRecord['tx_templavoila_ds'] = $ds;
$pageRecord['tx_templavoila_to'] = $to;
}
return $this->renderElement($pageRecord, 'pages');
}
This function checks the current page or search trough the rootline (TSFE) for the configured page template. The script does not check any TypoScript settings at all so I suppose thats not supported by TemplaVoila right now.
It should not be too hard extending this class with a custom function that will check some TypoScript settings.
I find many functions used in Bootstrap class in Zend Framework applications
like:
_initRoute()
_initLocale()
_initLayout()
.......
but i searched for it's reference but I fond nothing
Zend_Application_Bootstrap_BootstrapAbstract
Zend_Application_Bootstrap_Bootstrap
none of them contains any of these functions.
Where can i find the full reference of that functions?
Basically, these are resource plugins located in library/Zend/Application/Resource/. You may create also your custom ones.
See My detailed answer to very similar question which should fit also to this one.
Also, see BootstrapAbstract.php:
/**
* Get class resources (as resource/method pairs)
*
* Uses get_class_methods() by default, reflection on prior to 5.2.6,
* as a bug prevents the usage of get_class_methods() there.
*
* #return array
*/
public function getClassResources()
{
if (null === $this->_classResources) {
if (version_compare(PHP_VERSION, '5.2.6') === -1) {
$class = new ReflectionObject($this);
$classMethods = $class->getMethods();
$methodNames = array();
foreach ($classMethods as $method) {
$methodNames[] = $method->getName();
}
} else {
$methodNames = get_class_methods($this);
}
$this->_classResources = array();
foreach ($methodNames as $method) {
if (5 < strlen($method) && '_init' === substr($method, 0, 5)) {
$this->_classResources[strtolower(substr($method, 5))] = $method;
}
}
}
return $this->_classResources;
}
These function aren't defined anywhere, just in Bootstrap.php - these are called resource methods. At the bootstraping process, ZF automatically calls each function defined in Bootstrap.php which starts with _init.
Read more here: http://framework.zend.com/manual/en/zend.application.theory-of-operation.html